Bei der Bindung einer client-TCP-socket an einen bestimmten lokalen port mit Winsock, SO_REUSEADDR hat keine Wirkung
Bin ich verbindlich eine client TCP-socket an einen bestimmten lokalen port. Zu handle die situation, wo der sockel bleibt in TIME_WAIT
Zustand für einige Zeit, ich setsockopt()
mit SO_REUSEADDR
auf einem sockel.
Es funktioniert auf Linux, aber funktioniert nicht auf Windows, ich bekomme WSAEADDRINUSE
auf connect()
rufen, wenn die Vorherige Verbindung ist immer noch in TIME_WAIT
.
MSDN ist nicht genau klar, was passieren sollte mit client-sockets:
[...] Für server-Anwendungen, die Notwendigkeit zu binden, die mehrere sockets an dieselbe port-Nummer, sollten Sie die Verwendung
setsockopt
(SO_REUSEADDR
). Client-Anwendungen benötigen in der Regel keine call-bind-an all—connect wählt automatisch einen nicht verwendeten Anschluss. [...]
Wie kann ich diese vermeiden?
es ist eine Anforderung von dem externen system ich bin die Anbindung, und die ist unmöglich zu vermeiden.
können Sie gemeinsam einen funktionierenden code Stück für die Bindung an einen client-socket auf Linux?
meine Frage: stackoverflow.com/questions/4711608/...
InformationsquelleAutor Alex B | 2010-04-09
Du musst angemeldet sein, um einen Kommentar abzugeben.
Beim erstellen eines socket mit
socket()
, es hat nur ein Typ und eine Protokoll-Familie. Das ideal ist, umbind()
es zu einer lokalen IP-Adresse:port zu.Den Fehler, den Sie erwähnt passiert normalerweise, wenn die Letzte Verbindung zu dem gleichen host:port nicht haben, um ein ordnungsgemäßes Herunterfahren (FIN/ACK FIN/ACK). In diesen Fällen, der sockel bleibt in
TIME_WAIT
Staat für einen bestimmten Zeitraum (OS-abhängig, aber einstellbar).Was dann geschieht, ist, wenn Sie versuchen, um
connect()
auf demselben host und mit demselben port, verwendet es die Standard-socket-name/Adresse/port/etc, aber diese Kombination ist bereits in Ihrem zombie - Buchse. Um dies zu vermeiden, können Sie durch ändern der lokalen IP-Adresse:port zum herstellen der Verbindung verwendet, die durch aufrufenbind()
nachdem die socket-Erstellung, die Bereitstellung dersockaddr
struct gefüllt mit Ihrer lokalen Adresse und einer random port.UPDATE: Wie mit einem bestimmten lokalen port erforderlich ist, erwägen Sie
SO_LINGER
mitl_onoff=1
undl_linger=0
so dass Ihre Steckdose wird nicht blockiert, aufclose
/closesocket
ist, wird es einfach ignorieren, die Daten in der Warteschlange und es wird (hoffentlich) in der Nähe der fd. Als letzten Ausweg können Sie dieTIME_WAIT
Verzögerung, indem Sie den Wert dieses Registrierungsschlüssels (empfohlen!):Ist die Anpassung der TIME_WAIT-Wert zu einem niedrigeren Wert akzeptabel?
IMHO, es sollte nie die erste Sache, die berücksichtigt...
nicht schüchtern sein, wir freuen uns über Anregungen 🙂
Btw, ich habe aktualisiert die letzten Zeilen zu erwähnen, SO_LINGER. Es kam in den Sinn, nachdem @Len ' s Kommentar.
InformationsquelleAutor jweyrich
Du nicht angeben, welche Windows-Plattform laufen Sie, auf, die möglicherweise Einfluss auf die Dinge als vielleicht der Sicherheitsprinzipal, dass Sie unter (D. H. bist du admin?)...
Kann dies helfen: http://blogs.msdn.com/wndp/archive/2005/08/03/Anthony-Jones.aspx
InformationsquelleAutor Len Holgate
Vorsichtig sein bei der Bindung der lokale port, der NICHT die loopback-Adresse "127.0.0.1", um Verbindungs-timeouts. Besser nicht zum Auffüllen der sa_loc.sin_addr.s_addr an alle - das funktioniert Prima.
InformationsquelleAutor Pierre