C# Daten von TCP Server empfangen.

xparet0209

Ensign
Registriert
Okt. 2007
Beiträge
180
Hi CB'ler,
ich habe ein Server Programm das auf den String "login" Daten zurück liefert. Also habe ich folgende Methode aus einem Beispiel von MSDN kopiert und etwas umgeschrieben:

PHP:
public static void Login(string server, int port)
        {
            try
            {
                // Create a TcpClient.
                // Note, for this client to work you need to have a TcpServer 
                // connected to the same address as specified by the server, port
                // combination.
                TcpClient client = new TcpClient(server, port);

                // Translate the passed message into ASCII and store it as a Byte array.
                Byte[] data = System.Text.Encoding.ASCII.GetBytes("login");

                // Get a client stream for reading and writing.
                //  Stream stream = client.GetStream();

                NetworkStream stream = client.GetStream();

                // Send the message to the connected TcpServer. 
                stream.Write(data, 0, data.Length);

                Console.WriteLine("Sent: login");

                // Receive the TcpServer.response.

                // Buffer to store the response bytes.
                data = new Byte[256];

                // String to store the response ASCII representation.
                String responseData = String.Empty;

                // Read the first batch of the TcpServer response bytes.

                do
                {
                    //wait for answer of server 
                } while (!stream.DataAvailable);

                while (stream.DataAvailable)
                {
                    int bytes = stream.Read(data, 0, data.Length);
                    responseData += System.Text.Encoding.ASCII.GetString(data, 0, bytes);
                }
                Console.WriteLine("Recieved: {0}", responseData);
                // Close everything.
                //stream.Close();
                //client.Close();
            }
            catch (ArgumentNullException e)
            {
                Console.WriteLine("ArgumentNullException: {0}", e);
            }
            catch (SocketException e)
            {
                Console.WriteLine("SocketException: {0}", e);
            }
        }
Wie man erkennt muss ich in der ersten Schleife warten, bis der Server Daten anfangt abzuschicken. In der zweiten Schleife muss ich den Stream immer wieder teilweise auslesen und an einen String anheften, da die Daten des Streams größer sind als der Buffer.
Allerdings scheint mir das ganze recht unelegant, daher meine Frage: Gibt es eine praktischere Lösung um auf die Antwort der Servers zu warten und dann in einem Zug auszulesen?

mfg xparet0209
 
Zuletzt bearbeitet:
wie wärs wenn du den buffer größer machst? z.B. "data = new byte[1024]"??
Oder du nimmst einfach WCF her. Da hast du die Grundlagen innerhalb von nem Tag drauf und kannst viel bequemer und einfacher Netzwerkanwendungen erstellen.

Hab selber ne Zeit lang mit Sockets programmiert, aber bin nun auf WCF umgestiegen. Viel angenehmer ;-)
 
@ Zhen: Ich weiß allerdings nicht wie groß die ankommenden Daten sind, daher bringt es auch nichts wenn den buffer größer mache. Ich denke WCF wäre zu weit ausgeholt für meine zwecke

@GuardianAngel: Events hören sich passend an, aber die Klasse NetworkStream bietet kein Event an. Wie kann ich nun ein Event erzeugen, dass eine bestimmte Methode aufruft, wenn Daten im stream verfügbar sind?

PS: http://msdn.microsoft.com/en-us/library/aa645739(v=vs.71).aspx
Kann ich auch eine NewNetworkStream Klasse erstellen die von NetworkStream erbt usw.?
 
HI,

also die ankommenden Daten musst du immer geblockt auslesen. Sprich du weißt ja von vorneherein nicht wie groß deine Datenpakete sind die ankommen. Zumal Netzwerkprobleme auch dafür sorgen können das der Stream sich verändert oder nicht alle Zeichen enthält die du losgeschickt hast.

Überlege die ein Start- und ein Endsymbol das du mitsendest und auf die du reagierst, würde auch eine Fehlübertragung erkennbar machen. Diese Symbole zeigen wo dein Befehl anfängt und wo aufhört. Dann kannst du nach dem Konkatenieren den Befehl auslesen aus dem String (RegEx) und verarbeiten.

Wenn du den Stream byteweise ausließt kannst du vllt sogar etwas mit Events dann machen. Aber für das reine Auslesen ist das meines Erachtens schon eine gute Möglichkeit, wie sie die MSDN da anbietet.

In wie weit sich die NetworkStream Klasse vererben lässt kann ich dir nicht sagen, da hilft idr ein blick in die API. dort stehen idr die Methoden die reimplementiert werden müssen.
 
Abstrakte Methoden wirst du wenige bis gar keine finden ;)

Suche nach allen protected und public Methoden und hinterfrage sie, ob du sie nicht wiederverwenden kannst, oder ob sie gar stören. Falls sie stören oder eini anderes Verhalten haben sollen musst du sie neu schreiben.... (Grundlagen von OOP ;))

Gruß
 
Ok ich denke ich komme nicht drum herum Events zu benutzen, da ich merke, dass meine while Schleife öfters zu früh aufhört und das mitten in der Übertragung. Die empfangen Daten kann ich dann natürlich nicht weiter verarbeiten. Dabei müssten eigentlich noch Daten vom Server ankommen, doch stream.DataAvailable liefert seltsamerweise false zurück... Könnte das daran liegen, dass der Server zu langsam die Daten rausschickt? Und falls ja, kann ich einfach eine Pause in die while Schleife schreiben?
 
Zurück
Oben