Die wichtigste Frage wäre, ob du die Sockets im "blocking" oder "non-blocking" Mode verwendest. Ich vermute, dass letztere Variante der Fall ist, denn nur dann hast du die von mensch72 beschriebenen Probleme. Im blocking Mode blockiert der
send bzw.
recv Aufruf solange, bis die entsprechenden Buffer wieder Platz haben.
- noch besser wir es, wenn man sich selbst synchronisiert, in dem der Empfänger den Empfang der Daten durch rücksenden des empfangenen Blocks (hier also des StartOffsets) "quittiert" und man erst dann den nächsten Datenblock in den Socket zum Senden reinschreibt.
- sicher wird es, wenn der Empfänger bei seiner Quiitung noch eine Checksumme über die empfangenen Daten zurück schickt, welche der Sender vergleicht und bei Fehler den Datenblock z.B. nochmal wiederholt
Das ist beides bei Verwendung von
TCP komplett überflüssig und verursacht nur unnötigen Overhead.
TCP garantiert sowohl die komplette, als auch korrekte Zustellung sämtlicher Daten in unveränderter Reihenfolge.
- wichtig ist irgendein Sync!... man soll und darf den
OS-TCPIP-Stack nicht als quasi unendlich großen Datenpuffer mißbrauchen!
Man KANN (unter Windows) sogar nichtmal. Bei blocking Sockets hat man dieses Problem auch nicht, da die
send Aufrufe solange blockieren, bis der Empfänger mit
recv eine ausreichende Datenmenge empfangen hat (und somit wieder Platz im Sendebuffer frei ist). Dennoch sollte man die Datenmenge sowohl bei
send, als auch bei
recv begrenzen (z.b. auf 64KiB Blöcke) und dann in einer Schleife senden/empfangen.
Etwas komplizierter ist es bei "non-blocking" Sockets. Hier muss die Rückgabe von
send überprüft werden, da nicht garantiert ist, dass die
API sämtliche Daten in einem Rutsch verschickt.
Zitat von
MSDN send:
If no error occurs, send returns the total number of bytes sent, which can be less than the number requested to be sent in the len parameter. Otherwise, a value of SOCKET_ERROR is returned
Zitat von
MSDN send:
If no buffer space is available within the transport system to hold the data to be transmitted, send will block unless the socket has been placed in nonblocking mode. On nonblocking stream oriented sockets, the number of bytes written can be between 1 and the requested length, depending on buffer availability on both the client and server computers.
Zitat von
MSDN recv:
If no error occurs, recv returns the number of bytes received and the buffer pointed to by the buf parameter will contain this data received. If the connection has been gracefully closed, the return value is zero.
Otherwise, a value of SOCKET_ERROR is returned
Zitat von
MSDN recv:
For connection-oriented sockets (type SOCK_STREAM for example), calling recv will return as much data as is currently available—up to the size of the buffer specified. [..] If no incoming data is available at the socket, the recv call blocks and waits for data to arrive [..] unless the socket is nonblocking. In this case, a value of SOCKET_ERROR is returned