TcpSocket - Daten gehen verloren
-
Hallo,
wenn ich Daten über eine TCP-Verbindung mittels TcpClient/TcpListener sende, dann kommen in manchen Fällen die Daten nicht an. Und zwar passiert das, wenn das erste Byte der gesendeten Daten gleich 0x00 oder 0x43 oder 0x47 oder 0x48 ... (und noch einige andere) ist. Es kommen keine Daten durch, wenn einer davon an erster Stelle gesendet wurde. Auch nachfolgendes Senden geht ins Nirvana. Bis ein 0x0A (\r) gesendet wird, dann geht's wieder *g*
Wenn man ein anderes Byte (z.b. 0x01) zuerst sendet, dann geht alles normal. Alles kann gesendet werden inklusive der "bösen" Bytes oben.Beispiel:
0x47 0xA5 0x23 ... => kommt nix an
0x47 0xA5 0x23 0x0A 0xF3 ... => 0x0A F3 ... kommt an
0x01 0x47 0x34 0x00 0xED ... => 0x01 0x47 0x34 0x00 0xED ... kommt anEigentlich habe ich gedacht, dass ich über dem TCP-Layer beliebige Daten hin und her schieben kann. Gibt es da irgendwelche Kontrollsequenzen, die am Anfang auftreten können? Kennt jemand das Verhalten?
Vielleicht könnte jemand mal ausprobieren, ob das reproduzierbar ist. Beispielcode ist unten. Einfach in zwei
Visual Studio-Instanzen laufen lassen und im Client mal als aller erstes 'G' (0x47) + Enter tippen. Dann sollte beim
Server nix ankommen, auch nachfolgende Eingaben nicht.Server:
Akzeptiert einen Client und gibt alles aus was der ihm sendet.using System; using System.Threading; using System.Net.Sockets; using System.Net; using System.IO; namespace Testing { class Program { static void Main(string[] args) { TcpListener listener=new TcpListener(IPAddress.Any, 8080); listener.Start(); while (true) { Socket socket = listener.AcceptSocket(); Thread worker = new Thread(new ParameterizedThreadStart(Run)); worker.Start(socket); } } public static void Run(object param) { Console.WriteLine("Accepted: " + ((Socket)param).RemoteEndPoint.ToString()); BinaryReader reader = new BinaryReader(new NetworkStream((Socket)param)); try { while (true) Console.WriteLine("{0:X}", reader.ReadByte()); } catch (Exception) { Console.WriteLine("Disconnected: " + ((Socket)param).RemoteEndPoint.ToString()); } } } }
und der Client:
Verbindet zum Server und sendet das erste Zeichen einer Eingabe auf der Konsole an den Server. (Leere Eingabe => 0xA)using System; using System.Net.Sockets; using System.IO; namespace ClientTest { class Program { static void Main(string[] args) { TcpClient client = new TcpClient("localhost", 8080); BinaryWriter writer = new BinaryWriter(client.GetStream()); string buffer; while (true) { buffer = Console.ReadLine(); if (buffer.Length == 0) writer.Write((byte)0xA); else writer.Write((byte)buffer[0]); } } } }
Bin für jede Rückmeldung dankbar!
-
Ich würde mal reinsteppen, und gucken was Write bzw. ReadByte so machen.
-
Wer entleert eigentlich den Stringpuffer buffer im Client?
-
Write sendet erfolgreich. Read wartet auf eine Eingabe, ohne das etwas ankommt.
Es wäre nett, wenn jemand mal den Code so laufen lassen könnte um mir zumindest zu bestätigen dass es nicht an meinem System liegt.
Danke
-
Also ich habe es mal getestet. Wenn ich beide Anwendungen starte, 'G' und '\n' im Client eingebe, erscheint auf dem Server die Ausgabe 47.
-
Danke für's Ausprobieren! Dann liegt's wohl an mir. Welche Frameworkversion hast Du verwendet?
-
VS 2008
Er hatte 3.5 standardmäßig aktiviert. Ich habe es auf 2.0 zurückgesetzt, damit kann man ebenfalls G's senden.
-
Das ist wirklich eigenartig. Ich habe es jetzt auf drei Rechnern getestet und auf keinem hat es funktioniert.
Nur um nochmal sicher zu gehen: Die Daten kommen nur dann nicht an, wenn das 'G' als aller erstes gesendet wird. Wenn vorher etwas anderes kommt (z.B. ein 'a'), dann kommt alles an, auch 'G's. @witte: geht das bei Dir auch?
Wenn ja, dann weiß ich nicht mehr weiter...
Auf jeden Fall danke für Deine Unterstützung!
-
Ja, ich starte beide Anwendungen gebe als erstes 'G' ein, Enter und das G erscheint.
Gibt es irgendwelche Probleme mit Personal Firewalls oä?
Du kannst Server und Client auf zwei verschiedenen Rechnern starten und den Netzwerkverkehr mit einem Sniffer wie z.B. Ethereal prüfen (würde ich jetzt machen).
-
Hab auch einen Rechner gefunden, auf dem es geht. Da läuft Windows Server 2003.
Es läuft keine Firewall. Ausserdem wäre es seltsam, dass einige Pakete durchkommen und andere nicht (abhängig vom Payload)?
Der Sniffer sieht bei einem 'G' keine Daten, die bleiben also im Client hängen.
Ich installier jetzt meine Frameworks neu! So'n Mist aber auch.
Edit: BTW: wenn ich telnet als client nehme geht es auch nicht. *schultern zuck*
-
Der Port war's! Auf 8080 wurden die Daten wohl im Sinne von HTTP interpretiert.
Und da gibt es "GET ..." und "HTTP..." und "POST ..." und sonstwas, weswegen wohl 'G' und 'H' und 'P' ... nicht gingen!2 Tage im Eimer!
@witte:
Vielen Dank! Ohne Dich hätte es vielleicht noch ein Paar mehr Tage gebraucht!
Hast Du einen anderen Port verwendet?
-
_O_M_G_
Dann musst Du aber etwas dazwischen haben, ein Proxy oder sonstwas. Normalerweise werden solche Daten nicht interpretiert. Ich habe Deinen Quelltext unverändert verwendet, also auch Port 8080.
-
Dann musst Du aber etwas dazwischen haben, ein Proxy oder sonstwas.
Jo. Sieht danach aus als ob da eine Firewall auf Portebene die üblichen HTTP filtern würde. Zum auf Viren/Exploits prüfen oder was auch immer.
Oder ein transparenter Webcache.