TCP ist ein Stream-Protokoll. D.h. es gibt auf der TCP-Ebene keine Pakete (ausser 1 Byte). Paketgrenzen müssen auf der Protokollebene implementiert werden. Receive() muss also in einer Schleife aufgrufen werden. Wenn Receive() 0 zurückgibt, dann heisst das, dass der Sender die Verbindung geschlossen hat.
Also etwa so (geschweifte Klammern durch eckige ersetzen wegen BBCode):
byte{} buf = new byte{512}; int empfangenebytes = 0; int anzahl = 0; do { empfangenebytes = socket.Receive(buf, anzahl, buf.Size(), SocketFlags.None); anzahl += empfangenebytes; } while(anzahl<4 && empfangenebytes>0);
TCP-Verbindungen sind zuverlässig - d.h. wenn nicht alle gesendeten Daten ankommen wird im schlimmsten Fall ein Fehler erzeugt. Wenn keine Fehler erzugt wird dann werden die Daten korrket gesendet.
Das Problem wird dann wohl beim Senden der Daten auftreten.
Afaik ist nicht sichergestellt, dass alle gesendeten Daten in einem Rutsch gelesen werden können. Ebenfalls kann es sein, dass der Client nicht alle Daten in einem Rutsch sendet! Ich prüfe in solchen Fällen den Rückgabewert der lesenden Funktion und rufe diese ggf. erneut auf, um den Rest zu empfangen.
Die schockierende Tatsache über TCP/IP ist, dass es per Spezifikation zwar zuverlässig ist, aber keine Datagrammgrenzen respektiert. D.h. wenn Du in drei send-Calls z.B. 300, 400 und 500 Bytes schickst bevor Du den Socket schließt, liegt es innerhalb der Spezifikation, dass recv diesen Datenstrom als vier Pakete zu 200, 250, 350 und 400 Bytes empfängt.
Dieses Verhalten ist in der Praxis aber so selten, dass viele Programme mit der Annahme, dass Paketgrenzen respektiert werden, arbeiten und es (meist) überleben.