Ich habe ein kleines Programm geschrieben, das mit einem Server an einem bestimmten Port interagiert. Das Programm funktioniert gut, aber:
Sobald das Programm unerwartet beendet wurde und seitdem diese Socket-Verbindung im CLOSE_WAIT
Status angezeigt wird . Wenn ich versuche, ein Programm auszuführen, bleibt es hängen und ich muss es schließen, wodurch sich noch mehr CLOSE_WAIT
Socket-Verbindungen ansammeln .
Gibt es eine Möglichkeit, diese Verbindungen zu spülen?
Antworten:
CLOSE_WAIT
bedeutet, dass Ihr Programm noch ausgeführt wird und den Socket nicht geschlossen hat (und der Kernel darauf wartet). Fügen Sie hinzu-p
,netstat
um die PID zu erhalten, und töten Sie sie dann stärker (beiSIGKILL
Bedarf mit). Das sollte deineCLOSE_WAIT
Steckdosen loswerden . Sie können auch verwendenps
, um die PID zu finden.SO_REUSEADDR
ist für Server undTIME_WAIT
Sockets, gilt also hier nicht.quelle
Wie von Crist Clark beschrieben .
quelle
close()
oderclosesocket()
, je nachdem, welche Plattform Sie verwenden.Ich habe auch das gleiche Problem mit einem neuesten Tomcat-Server (7.0.40). Es reagiert einmal für ein paar Tage nicht mehr.
Um offene Verbindungen anzuzeigen, können Sie Folgendes verwenden:
Wie in diesem Beitrag erwähnt , können Sie
/proc/sys/net/ipv4/tcp_keepalive_time
die Werte anzeigen. Der Wert scheint in Sekunden zu sein und ist standardmäßig 7200 (dh 2 Stunden).Um sie zu ändern, müssen Sie bearbeiten
/etc/sysctl.conf
.quelle
Auch wenn zu viele CLOSE_WAIT-Verbindungen bedeuten, dass im ersten Code etwas mit Ihrem Code nicht stimmt, wird dies als nicht bewährte Methode akzeptiert.
Vielleicht möchten Sie Folgendes überprüfen: https://github.com/rghose/kill-close-wait-connections
Dieses Skript sendet die ACK, auf die die Verbindung gewartet hat.
Das hat bei mir funktioniert.
quelle
Es sollte erwähnt werden, dass die
Socket
Instanz sowohl im Client- als auch im Serverende explizit aufgerufen werden mussclose()
. Wenn dann auch nur eines der Endenclose()
aufgerufen wird, bleibt der Socket im Status CLOSE_WAIT.quelle
Sie können Sockets mit
ss
Befehl zwangsweise schließen . Derss
Befehl ist ein Tool zum Speichern von Socket-Statistiken und zeigt Informationen auf ähnliche Weise (obwohl einfacher und schneller) wie netstat an.Führen Sie dies aus (als root), um einen Socket im Status CLOSE_WAIT zu beenden.
quelle
Es ist auch erwähnenswert, dass, wenn Ihr Programm einen neuen Prozess erzeugt, dieser Prozess möglicherweise alle geöffneten Handles erbt. Selbst nach Ihrem eigenen Programmabschluss können diese geerbten Handles über den verwaisten untergeordneten Prozess noch aktiv sein. Und sie zeigen sich in netstat nicht unbedingt gleich. Trotzdem bleibt der Socket in CLOSE_WAIT hängen, während dieser untergeordnete Prozess aktiv ist.
Ich hatte einen Fall, in dem ich ADB ausführte. ADB selbst erzeugt einen Serverprozess, falls dieser noch nicht ausgeführt wird. Dies erbte anfangs alle meine Handles, zeigte sich jedoch bei meiner Untersuchung nicht als Eigentümer eines dieser Handles (das gleiche galt sowohl für MacOS als auch für Windows - ich bin mir bei Linux nicht sicher).
quelle