2016-04-13 4 views
2

Ich habe versucht, UDP-Sockets zu verwenden. Auf dem Client habe ich eine bestimmte Zeit eingestellt und wenn ich recv() anrufe, überprüfe ich den Rückgabewert und wenn es kleiner als 0 ist, überprüfe ich, ob errno EAGAIN oder EWOULDBLOCK ist. Wenn der Fehler nicht einer dieser 2 ist, versuche ich den Server erneut zu verbinden. Jetzt muss ich feststellen, ob das andere Ende der Verbindung geschlossen ist oder nicht. Neben der Überprüfung auf den Rückgabewert von recv() gleich "0" muss ich nach Fehlern suchen? Setzt recv() errno, wenn das andere Ende des Sockets geschlossen ist? Wenn nicht, warum errno nicht eingestellt ist?Warum Recv() Errno nicht gesetzt, wenn das andere Ende der Socket-Kommunikation geschlossen ist?

+4

Fragen über das "andere Ende" eines UDP-Sockets ist wie Fragen über das "andere Ende" eines Postfachs ... die Pakete durch einen UDP-Socket können von vielen verschiedenen Zielen kommen (oder gehen). –

+0

Wenn Sie "Verbindungen" wollen, dann möchten Sie TCP oder möglicherweise SCTP. –

Antwort

8

UDP hat keine Verbindungen, und daher können Sie nicht leicht ableiten, ob das andere Ende den Sockel geschlossen hatte oder nicht. Wenn Sie Verbindungen benötigen, müssen Sie TCP verwenden.

Jedoch sendet oft ein Empfänger sendet eine ICMP-Antwort, wenn mit einem UDP-Port, der nicht geöffnet ist, kontaktiert wird; dies kann als Rückgabewert von recv oder send signalisiert werden; Unter Linux kann dies für alle UDP-Sockets passieren, und auf BSD scheint es nur für "verbundene" UDP-Sockets zu gelten.

In jedem Fall können Sie nicht zwischen einem

  • ICMP in Richtung Absender ableiten durch Firewall
  • UDP Richtung Empfänger gefiltert durch Firewall
  • UDP gefiltert wird, erfolgreich an den Empfänger geliefert werden

Also würde ich die mögliche Signalisierung von UDP-Fehlern eine "nette Ergänzung" betrachten, aber nicht etwas, auf das man sich verlassen kann.


TCP ist sehr analog zu einem Telefonanruf, während UDP eher wie Postfächer ist. Wenn Sie einen Brief an eine nicht existierende Adresse senden, die keine Mailbox hat, können Sie Ihren Brief 2 Wochen später mit einem Aufkleber zurück erhalten, der besagt, dass die Post nicht zugestellt werden konnte.

Wenn Sie Ihren Brief nicht zurückbekommen, dann hat entweder der Empfänger ihn erhalten, der Postmann hat ihn gestohlen, er wurde in einer Sortiermaschine zerfetzt, oder vielleicht hat ein Hund den Brief gegessen; der einzige Weg, um zu wissen, dass es tatsächlich erfolgreich empfangen wurde, wäre, dass der Empfänger einen anderen Brief zurücksendet, der den Empfang bestätigt.

+0

Danke Antti. In unserem Projekt benutzen wir UDP und auf dem Client benutze ich recv() call to mit einem Timeout. In einigen Fällen starb der Server und es gibt einen Überwachungsagenten in unseren Systemen, der den Prozess überwacht und wenn ein Prozess stirbt, startet er den Prozess neu. Da ich nur überprüfe, ob der Rückgabewert os recv() kleiner als 0 ist, höre ich den alten Socket ab und obwohl der Server neu gestartet wird, kann ich die Nachrichten nicht abrufen. Können Sie mir bitte eine Idee vorschlagen, wie Sie das beheben können? – kadina

+0

@Kadina: Das klingt sehr komisch. Da UDP keine Verbindung ist, sollte ein empfangender UDP-Socket alles empfangen, was an seine IP und seinen Port gesendet wird. Bist du sicher, dass die andere Seite nicht einfach vergessen hat, dir zu schicken? –

+0

@Kadina: Zum Beispiel muss ein Syslog-Daemon, der auf UDP-Syslog-Nachrichten wartet, seinen Socket nicht erneut öffnen. Es erhält nur Nachrichten. –

Verwandte Themen