Da es sich um eine Multi-Frage, ich werde mein Bestes tun, um jeden Teil zu Ihrer Zufriedenheit zu beantworten:
1) Es war meine Erfahrung mit ASIO-Sockets, die der Destruktor beim Schließen des Sockets handhabt. Ich habe mich jedoch nur mit TCP-Sockets beschäftigt. Der beste Weg, dies zu überprüfen, besteht darin, einfach den Code für den Destruktor zu betrachten, um zu sehen, ob er etwas ähnlich wie ein Schließen tut. Ich weiß, dass Boost-Code ein wenig trickreich sein kann, so dass es am einfachsten ist, einfach ein kleines Beispielprogramm zu erstellen, das einen UDP-Socket öffnet und es dann zerstört. Auf diese Weise können Sie den Code in einem Debugger durchlaufen, um der Logik zu folgen.
Da die Designer von Boost dies bei TCP-Sockets berücksichtigten, fällt es mir schwer, mir vorzustellen, dass sie das nicht auch für UDP-Sockets tun würden.
2) Rufen Sie shutdown()
nur an, wenn Sie glauben, dass es notwendig ist, zu verhindern, dass ein Code eine zukünftige recv
und/oder send
auf dem Sockel ausführt. Es ist normalerweise nicht erforderlich, obwohl ich gesehen habe, dass es in TCP-Sockets verwendet wird, um den Socket zu zwingen, eine RST
zu senden, wenn es geschlossen ist (im Gegensatz zu dem standardmäßigen "anmutigen" Herunterfahren, bei dem ausstehende Sends verarbeitet werden).
3) Sie können sich Sockets als zweikanalige Kommunikationsform vorstellen: eine zum Lesen, die andere zum Senden. Sie können beide unabhängig voneinander herunterfahren, und Sie können weiterhin einen Kanal verwenden, wenn der andere heruntergefahren ist (d. H. Sie können immer noch nach dem Herunterfahren zum Senden empfangen und umgekehrt). Das Schließen eines Sockets ist identisch mit dem Aufruf von shutdown sowohl bei recv als auch bei send.
Das Herunterfahren für recv verhindert einfach, dass Ihr Code keine weiteren Daten mehr lesen kann. Wenn Sie dies versuchen, erhalten Sie einen Socket-Fehler. Wenn die andere Seite der Verbindung versucht, Daten an Sie zu senden, wird ebenfalls ein Fehler angezeigt (es tut uns leid, wieder in die TCP-Welt zu wechseln, aber ich glaube, dass eine RST
zurück an den Absender gesendet wird).
Das Herunterfahren zum Senden verhindert ebenfalls, dass Ihr Code weitere Daten sendet. Wenn Speicher mir richtig dient, sieht das identisch aus, was passiert, wenn Sie einen Socket schließen (ein Null-Länge-Paket wird gesendet, um der anderen Seite zu signalisieren, dass der bestimmte Kanal heruntergefahren wurde). Alle zukünftigen Sendeversuche geben einen Fehler zurück.
4) Sie müssen Ihre Dokumente überprüfen, um sicher zu sein. MSDN wird Ihnen einen ziemlich guten Hinweis geben, obwohl ich nicht weiß, dass ich es für autoritativ halten würde.
Danke, ich habe einige dieser herausgefunden, aber ich bin immer noch nicht sicher, ob close() wirklich in der Destruktor der Buchse genannt wird. Was ich wirklich nicht gemunkelt hatte, war die enge Verbindung zwischen Boost Asio und traditioneller Netzwerkprogrammierung. Sowohl Ihre Erklärung von shutdown() als auch der Vorschlag, in msdn-Socket-Fehlercodes zu suchen, legen dies nahe. +1 – Torleif
Froh ich könnte helfen :) – Brian
FWIW, Aufruf .shutdown (BEIDE) auf einem UDP-Socket funktioniert für mich auf Windows, aber explodiert unter Linux, weil der Socket nicht verbunden ist. –