C# Bild von Client auf Server schicken

blume666

Cadet 3rd Year
Registriert
März 2009
Beiträge
44
Hallo leute,


ich bau mir gerade 2 kleine Programme. Das eine soll ein Bild zum anderen verschicken. Ich habe schon viel probiert aber es hat nie wirklich geklappt.

Erst habe ich es mit Sockets versucht... Dann mit Streams... Habe also immer erst das Bild in ein Bytearray umgewandelt und dann in einen Stream geschrieben. Da wenn überhaupt aber nur der header des Bildes ankam, habe ich versucht das ganze zu Segmentieren. Habe mir einen 2. Stream als eine Art Steuerleitung aufgebaut.

Naja was soll ich sagen. Es will nich klappen! Habt ihr vielleicht damit erfahrungen gemacht? Oder ein gutes Tutorial am Start, dass sich auch mit Bildern versenden beschäftigt? Wenn dann hat google mir nur welche für kleine Textzeilen ausgespuckt.

Und was ich auch noch suche wäre ein Tutorial zu AsyncCallbacks.


mfg blume
 
ja danke! das ding hatte ich auch schon in der hand! fand es aber zu komplex! nun habe ich andere kotschnipselgefunden. aber es funktioniert.

Nun habe ich das Problem, dass ich das gesendete Bild anzeigen lassen möchte! Also Wenn eins eintrifft möchte ich es anzeigen lassen. Nur greift Das Programm die ganze zeit auf die Datei zu und ich kann sie einfach nicht zwischenspeichern um weiter mit ihr zu arbeiten!

Ich stell mal den quellcode hier rein. vielleicht weiß ja einer Rat wie ich wo ansetzen kann. Bin echt ein absoluter neuling in sachen tcp/socket programmierung.


Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.IO;

namespace SERVER
{
    public partial class Form1 : Form
    {
        Thread t1;
        string dateiname = "test.jpg";
        int flag = 0, port;
        string receivedPath = "yok";
        public delegate void MyDelegate();
        

        public Form1()
        {
            InitializeComponent();
        }

        public class StateObject
        {
            // Client socket.
            public Socket workSocket = null;

            public const int BufferSize = 1024;
            // Receive buffer.
            public byte[] buffer = new byte[BufferSize];
        }

        public static ManualResetEvent allDone = new ManualResetEvent(false);

        public void StartListening(Object data)
        {
                port = (int)data;
                byte[] bytes = new Byte[1024];
                IPEndPoint ipEnd = new IPEndPoint(IPAddress.Any, port);
                Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                try
                {
                    listener.Bind(ipEnd);
                    listener.Listen(100);
                    while (true)
                    {
                        allDone.Reset();
                        listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
                        allDone.WaitOne();              
                    }  
                }
                catch (Exception ex)
                {

                }            
        }

        public void AcceptCallback(IAsyncResult ar)
        {
            allDone.Set();


            Socket listener = (Socket)ar.AsyncState;
            Socket handler = listener.EndAccept(ar);


            StateObject state = new StateObject();
            state.workSocket = handler;
            handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
            new AsyncCallback(ReadCallback), state);
            flag = 0;
        }

        public void ReadCallback(IAsyncResult ar)
        {

            int fileNameLen = 1;
            String content = String.Empty;
            StateObject state = (StateObject)ar.AsyncState;
            Socket handler = state.workSocket;
            int bytesRead = handler.EndReceive(ar);
            if (bytesRead > 0)
            {

                if (flag == 0)
                {
                    fileNameLen = BitConverter.ToInt32(state.buffer, 0);
                    string fileName = Encoding.UTF8.GetString(state.buffer, 4, fileNameLen);
                    receivedPath = fileName;
                    flag++;
                }
                if (flag >= 1)
                {
                    BinaryWriter writer = new BinaryWriter(File.Open(receivedPath, FileMode.Append));
                    if (flag == 1)
                    {
                        writer.Write(state.buffer, 4 + fileNameLen, bytesRead - (4 + fileNameLen));
                        flag++;
                    }
                    else
                    {
                        writer.Write(state.buffer, 0, bytesRead);
                    }
                    writer.Close();
                    handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
                    
                }
            }
            else
            {
                Invoke(new MyDelegate(LabelWriter));
            }

        }
        public void LabelWriter()
        {
            listBox1.Items.Add(">>\tDaten wurden gesendet und gespeichert.");
        }
    
        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            t1.Abort();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            try
            {
                ParameterizedThreadStart pts = new ParameterizedThreadStart(StartListening);
                Thread t1 = new Thread(pts);

                textBox1.Enabled = false;

                port = System.Convert.ToInt32(textBox1.Text);
                t1.Start((object)port);

                listBox1.Items.Add(">>\tServer wurde gestartet. PORT: " + System.Convert.ToString(port));
            }
            catch
            {
                listBox1.Items.Add(">>\tFehler beim Serverstart über Port " + System.Convert.ToString(port));
            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            t1.Abort();
        }
    }

}
 
1.) Ich verwende immer die Klassen TcpListener und TcpClient. Beim Listener brauchst du nur einen Port im Konstruktor angeben, den Listener starten und dann in einer Schleife AcceptTcpClient machen. Der TcpClient braucht nur Connecten. Danach kannst du dir auch den TcpClients den Networkstream herausholen.

2.) Beim Lesen/Schreiben von Dateien ist es wichtig, die Datei nach der Verwendung wieder zu schließen. Wenn du dir das Ganze sparen willst, dann gibt es auch die Funktionen ReadAllBytes bzw. WriteAllBytes.

3.) Wenn du sagt, dass du nur den Header des Bildes bekommen hast, dann bist du wahrscheinlich über die selbe Falle gestolpert wie ich bei meinem ersten Versuch (lange, lange ist es her :D). Die Funktion Read(buffer,offset,length) bekommt zwar eine Länge übergeben, kann aber auch weniger Bytes lesen, wenn weniger im Cache waren. Da musst du immer den Rückgabewert prüfen.

4.) Alles, was du verschicken willst, muss in ein Byte Array umgewandelt werden. Ich würde das immer manuell machen. Du kannst ein Image dann auch sehr leicht aus dem RAM laden mit einem Memorystream, den du dann dem Graphicobject übergibst (Klasse Bitmap)

5.) Wenn du Daten übers Netzwerk übertragen willst, dann ist es von Vorteil vorher die Länge mit zu senden. Ich verwendet folgendes Protokoll:
MessageType: Byte
MessageLength: Integer (little endien codiert)
Message: Byte()

P.S.: Wenn du auch Strings verschicken willst, solltest du dir auch Gedanken um die Codierung machen. Ich bevorzuge hier UTF8.
 
jau danke!

mein problem liegt im moment noch am anzeigen des bildes... ich muss es wie man sieht in einem binarywriter öffnen (mit stream hab ichs auch shcon versucht), aber durch den FileMode.Appand scheitert jeglicher lese versuch!

Also: Ich kann es nicht anzeigen. Hat noch wer eine Idee?
 
Zurück
Oben