UDP Sendeverhalten nach connect ()

8
%Vor%

Der obige Code wird kompiliert, um auf einer Linux-Maschine zu laufen.

Nehmen Sie an, dass der obige Code Daten an eine Maschine mit der IP-Adresse 128.88.143.113 sendet. Kein UDP-Socket ist an den Port 9090 at 128.88.143.113 gebunden.

In der Schleife while ist der erste Aufruf von send() erfolgreich (das Paket geht tatsächlich auf den Draht; es wurde mit trace überprüft) und der zweite send() schlägt mit Connection refused fehl. Die third send() ist erfolgreich und die vierte fehlschlägt und so weiter.

Ich vermute, dass nach dem ersten send() der Stack eine ICMP-Fehlermeldung (in tcpdump auf dem Linux-Rechner gesehen) erhält, die in der Socket-Struktur gespeichert ist. Das zweite send() schlägt fehl, wenn dieser Fehler erkannt wird und kein Paket tatsächlich gesendet wird. Die zweite send() löscht auch den Fehler in der Socket-Struktur. Daher ist die dritte send() erfolgreich und die vierte fehlschlägt und so weiter.

Fragen:

  1. Ist diese Annahme richtig?
  2. Was sollte das richtige Verhalten sein? Gibt es einen RFC-Standard, der ein solches Verhalten definiert?
  3. Da UDP keinen Verbindungsstatus aufrechterhält, sollte nicht jedes send() erfolgreich sein?
Raju V 09.12.2010, 10:29
quelle

5 Antworten

5

Nach der Linux-man-Seite für udp :

  

Alle schwerwiegenden Fehler werden an die   Benutzer als Fehler zurückgeben, auch wenn die   Steckdose ist nicht verbunden. Das beinhaltet   asynchrone Fehler, die von der   Netzwerk. Sie erhalten möglicherweise einen Fehler für eine   früheres Paket, das auf dem gesendet wurde   gleiche Steckdose. Dieses Verhalten ist unterschiedlich   von vielen anderen BSD-Sockets   Implementierungen, die keine bestehen   Fehler, außer der Socket ist verbunden.   Linux Verhalten von RFC 1122 beauftragt wird.

Insbesondere das RFC (4.1.3.3) heißt es:

  

UDP MUSS alle ICMP-Fehler an die Anwendungsebene weitergeben   Nachrichten, die es von der IP-Schicht erhält. Konzeptionell   zumindest kann dies mit einem Upcall zu den erreicht werden   ERROR_REPORT-Routine

    
Hasturkun 09.12.2010 11:52
quelle
3

Ihre Hypothese ist richtig. Die Linux-UDP (7) -Mantseite beschreibt die Situation so:

  

Alle schwerwiegenden Fehler werden übergeben   an den Benutzer als Fehler zurückgeben sogar   wenn der Sockel nicht angeschlossen ist.   Dies schließt asynchrone Fehler ein   aus dem Netzwerk erhalten. Du darfst   Erhalte einen Fehler für ein früheres Paket   das wurde an derselben Buchse gesendet.
  Dieses Verhalten unterscheidet sich von vielen anderen   BSD-Socket-Implementierungen, die dies nicht tun   Übergeben Sie alle Fehler, es sei denn, der Socket ist   in Verbindung gebracht. Das Verhalten von Linux ist   Mandat von RFC 1122 .

     

Wenn die Option IP_RECVERR ist   aktiviert alle Fehler sind in der gespeichert   Socket-Fehlerwarteschlange und kann empfangen werden   von recvmsg(2) mit der    MSG_ERRQUEUE flag gesetzt.

    
caf 09.12.2010 11:53
quelle
2

Es wäre interessant, den entsprechenden Code mit sendto() anstatt mit connect() und send() zu vergleichen.

Fällt der angezeigte Code auf die gleiche Weise aus, wenn Sie zwischen den einzelnen Sendevorgängen einen bestimmten Zeitraum belassen, dh, dass der ICMP-Fehlerzustand für eine gewisse Zeit im Socket verbleibt oder der zweite send() weiterhin fehlschlägt? Wenn du es verlassen hast, sagen wir, eine Stunde?

Ich erwarte, dass Ihre Annahme richtig ist, der Netzwerkstapel versucht, clever zu sein. Es gibt keinen anderen Punkt, an dem die Verbindung zurückgewiesen werden könnte, da beim Senden des connect() -Aufrufs nichts gesendet wird. Sie speichert einfach die angegebene Adresse, so dass der Socket "logisch" verbunden ist und Aufrufe von send() dann funktionieren können / p>     

Len Holgate 09.12.2010 11:39
quelle
1

Um am anderen Ende zu beginnen, wenn Sie einen UDP-Socket anschließen, können Sie Fehler beim nächsten Senden sammeln. Wenn du das nicht willst, verbinde dich nicht!

    
EJP 09.12.2010 10:43
quelle
0

Ich hatte das gleiche Problem; und das liegt daran, dass die udp-Nachrichtenwarteschlange gefüllt ist, wenn niemand zuhört und die Warteschlange löscht.

    
Chris Maes 12.01.2017 13:30
quelle

Tags und Links