Einzelnen Beitrag anzeigen

Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#5

AW: Multi Socket Transfer

  Alt 19. Jul 2017, 15:17
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 MSDN-Library durchsuchensend bzw. MSDN-Library durchsuchenrecv 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 MSDN-Library durchsuchensend Aufrufe solange blockieren, bis der Empfänger mit MSDN-Library durchsuchenrecv eine ausreichende Datenmenge empfangen hat (und somit wieder Platz im Sendebuffer frei ist). Dennoch sollte man die Datenmenge sowohl bei MSDN-Library durchsuchensend, als auch bei MSDN-Library durchsuchenrecv 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 MSDN-Library durchsuchensend ü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
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)

Geändert von Zacherl (19. Jul 2017 um 15:33 Uhr)
  Mit Zitat antworten Zitat