Ich habe ein Problem zu verstehen, was recv()/recvfrom() von einem nicht blockig UDP-Socket zurückkehrt.nicht-blockierende Udp-Socket-Programmierung in C: Was bekomme ich?
Etwas präziser und im Vergleich zu TCP (bitte korrigieren Sie mich, wenn ich falsch):
Eine blockierenden Socket (TCP oder UDP) nicht von einem recv() zurückgeben, bis sind einige Daten im Puffer. Dies könnte eine bestimmte Anzahl von Bytes (TCP) oder ein vollständiges Datagramm (UDP) sein.
Ein nicht blockierender TCP-Socket gibt entweder EWOULDBLOCK (linux)/WSAEWOULDBLOCK (Windows) oder die Bytes zurück, die sich derzeit im Puffer befinden. Da TCP-Daten ein Stream sind, spielt es keine Rolle, wie viele Bytes zurückgegeben werden.
Nun ist die Frage:
- Eine nicht-blockierende UDP-Sockets auch WOULDBLOCK zurückgibt (Linux)/WSAEWOULDBLOCK (Fenster), wenn es keine Daten verfügbar sind. Aber wenn Daten verfügbar sind, gibt ein nicht blockierender UDP-Socket nur ein paar Bytes zurück, was bedeuten kann, dass Sie nur die Hälfte eines Datagramms bekommen ODER liefert ein UDP-Socket immer vollständige Datagramme?
Edit:
Was ich mit „Hälfte eines Datagramms“ bedeuten, ist: Was passiert, wenn ich recv() aufrufen, in genau der Moment, wenn die Buchse zur Zeit ein Datagramm empfängt. In diesem Moment befinden sich einige Bytes im Puffer, aber das Datagramm ist noch nicht vollständig.
Ihre Erklärungen und Kommentare sind willkommen. Vielen Dank!
Es scheint, als ob es möglich ist, ein MSG_TRUNC-Flag an 'recvmsg' in Linux zu übergeben und zu empfangen. Dokumentiert in der Manpage 'recv (2)'. In anderen Worten, vielleicht lese ich falsch, aber ich kann nur das Verwerfungsverhalten finden, das in der Manpage für 'socket (2)' dokumentiert ist, das es nur für 'SOCK_SEQPACKET' Sockets erwähnt. Ich habe diese nie persönlich benutzt. –
'MSG_TRUNC' als Argument zu' recv (2) 'ist kein Standard. Es ist weder auf FreeBSD noch auf Mac OS X verfügbar (die Systeme, auf die ich momentan zugreifen kann; wahrscheinlich auch für andere). 'MSG_TRUNC' ist unter Linux, FreeBSD und Mac OS X im' flags'-Member des 'struct msghdr' verfügbar, der an' recvmsg (2) 'übergeben wird. In jedem Fall wird das Datagramm abgeschnitten, wenn der übergebene Puffer nicht groß genug ist, sogar mit 'recv (2)' auf Linux. Der Aufrufer muss den Rückgabewert überprüfen und mit der Puffergröße vergleichen, wenn dort "MSG_TRUNC" verwendet wird. Es wird wissen, Daten sind verloren, aber es ist immer noch verloren. –
Danke! Dies bedeutet, UDP ist ** wirklich ** Paket orientiert ... – Uwe