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?
Antwort
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.
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
@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? –
@Kadina: Zum Beispiel muss ein Syslog-Daemon, der auf UDP-Syslog-Nachrichten wartet, seinen Socket nicht erneut öffnen. Es erhält nur Nachrichten. –
- 1. Ist die Funktion fprintf() für ihre Fehleranzeige errno gesetzt?
- 2. Der Vorgang ist nicht erlaubt, wenn das Objekt geschlossen wird
- 3. Wird free() gesetzt errno?
- 4. Rückruffunktion, wenn das untergeordnete Fenster geschlossen ist
- 5. Warum ist SqlConnection nicht entsorgt/geschlossen?
- 6. "Tag-Start ist nicht geschlossen" beim Kommentieren in das Anfangs- und Ende-Tag des XML-Elements
- 7. recv() gibt 0 zurück
- 8. SqLite-Datenbank wird nicht geschlossen, wenn in Unicode und PRAGMA journal_mode gesetzt ist
- 9. Wenn ein nonblocking recv mit MSG_PEEK erfolgreich ist, wird ein nachfolgendes recv ohne MSG_PEEK auch erfolgreich sein?
- 10. Force-Warnung, wenn Klasse nicht geschlossen ist
- 11. Konnte Eingabe nicht fokussieren, wenn der Hash gesetzt ist
- 12. Warum ist Drop erlaubt, auch wenn Effects = DragDropEffects.None gesetzt ist?
- 13. Der Betrieb ist nicht erlaubt, wenn das Objekt geschlossen ist VBA
- 14. Loop stoppt nicht wenn Flag gesetzt ist?
- 15. Verhindern, dass das erste Formular geschlossen wird, indem das andere geschlossen wird
- 16. Warum funktioniert der Rekursionscode nicht richtig? [Geschlossen!]
- 17. „Operation ist nicht erlaubt, wenn das Objekt geschlossen ist“, wenn die gespeicherte Prozedur Ausführen
- 18. MongoDB bind_ip funktioniert nicht, wenn es auf 0.0.0.0 gesetzt ist
- 19. ADODB.Recordset: Der Vorgang ist nicht erlaubt, wenn das Objekt geschlossen wird
- 20. JPA: Warum faul Felder geladen werden, wenn EntityManager geschlossen ist
- 21. DropDownListing zurücksetzen, wenn das modale Fenster geschlossen ist
- 22. Ungültiger Versuch, HasRows aufzurufen, wenn der Reader geschlossen ist
- 23. Befehl Ende mit einem Errno:: EEXIST Nachricht
- 24. Erkennung, wenn das "File Download" Popup geschlossen ist
- 25. winform automatisch schließen, wenn das Hauptformular geschlossen ist
- 26. Qt ein anderes Fenster öffnen, wenn das erste geschlossen ist
- 27. Warum konnte das Namensattribut nicht mit Javascript gesetzt werden?
- 28. Nicht gehen onMessageReceived, wenn die App geschlossen ist
- 29. Stoppen Sie das Video, wenn Modal geschlossen ist
- 30. Schließen Notepad ++, wenn das letzte Dokument geschlossen ist
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). –
Wenn Sie "Verbindungen" wollen, dann möchten Sie TCP oder möglicherweise SCTP. –