2009-12-23 4 views
15

Wann ist IPPROTO_UDP erforderlich?Wann ist IPPROTO_UDP erforderlich?

Gibt es jemals einen Fall, in dem UDP nicht das Standardprotokoll für SOCK_DGRAM ist? (Reale Fälle, nicht hypothetisch „es könnte sein“, bitte ")

dh was sind die Situationen, in denen die beiden folgenden Zeilen würden nicht identisches Verhalten erzeugen

if ((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1) 
if ((s=socket(AF_INET, SOCK_DGRAM, 0))==-1) 

Antwort

12

In Anbetracht dieser Erklärungen:

tcp_socket = socket(AF_INET, SOCK_STREAM, 0); 
udp_socket = socket(AF_INET, SOCK_DGRAM, 0); 
raw_socket = socket(AF_INET, SOCK_RAW, protocol); 

die ip(7) Handbuch Seite in linux sagt:

Die einzigen gültigen Werte für das Protokoll sind 0 und IPPROTO_TCP für TCP-Sockets und 0 und IPPROTO_UDP für UDP-Sockets. Für SOCK_RAW können Sie ein gültiges IANA IP-Protokoll definieren, das in RFC 1700 zugewiesenen Nummern definiert ist.

Diese beiden Zeilen in Ihren Fragen ergeben immer das gleiche Ergebnis.

+0

Ich denke, dass die Verwendung von 'IPPROTO_UDP' intsead von Null ist nicht das gleiche Ergebnis, wie Sie einen Socket erhalten, der Sie alle Header ausfüllen müssen. – WilliamKF

14

Einige Betriebssysteme (zB Linux Kernel nach 2.6.20) unterstützen ein zweites Protokoll für SOCK_DGRAM, genannt UDP-Lite. Wenn dies von Ihrem System unterstützt wird, wird es aktiviert, indem Sie IPPROTO_UDPLITE als drittes Argument für den Aufruf von socket() angeben.

Es unterscheidet sich von normalem UDP dadurch, dass die Prüfsummierung nur auf einen Teil des Datagramms angewendet werden kann. (Normalerweise ist die UDP-Prüfsummierung eine Alles-oder-Nichts-Maßnahme.) Auf diese Weise kann das Protokoll resistenter gegen Prüfsummenfehler aufgrund fragmentierter Übertragung sein, falls einige Fragmente außerhalb des Prüfsummenbereichs während des Transports verloren gegangen sind. Solange die Fragmente, die den Prüfsummenabschnitt bedecken, erfolgreich empfangen wurden, wird so viel wie möglich des Datagramms an die Anwendung geliefert.

Aus Gründen der Abwärtskompatibilität mit vorhandenem Code vermute ich (aber ich kann nicht garantieren), dass der Rufsockel (AF_INET, SOCK_DGRAM, 0) auch in Systemen, die zusätzlich UDP-Lite unterstützen, standardmäßig auf normalem UDP bleibt.