Ich kämpfe derzeit mit einer beschissenen (kundenspezifischen) Serversoftware, die ihre Verbindungen nicht richtig akzeptiert (geschrieben in Java von einem PHP-Programmierer, der noch nie zuvor mit Sockets, geschweige denn Threads, zu tun hatte). Ich vermute, dass ein Thread stirbt, bevor der Socket im Client-Thread richtig akzeptiert wird. Ich kann es nicht genau sagen, und eigentlich spielt es auch keine große Rolle, da die Software derzeit neu implementiert wird; die alte Version muss so lange am Laufen gehalten werden, bis die neue Version online geht, und zwar so zuverlässig wie möglich, aber ohne Zeit- und Kostenaufwand für das Debuggen der alten Codebasis.
Der Fehler manifestiert sich in der folgenden Netstat-Ausgabe; einige Verbindungen werden nie vom Kernel übertragen, um Speicherplatz zu nutzen (so interpretiere ich das, bessere Interpretationen sind willkommen):
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp6 228 0 192.0.2.105:1988 46.23.248.10:7925 ESTABLISHED -
tcp6 0 0 192.0.2.105:1988 221.130.33.37:9826 ESTABLISHED 14741/java
tcp6 0 0 192.0.2.105:1988 46.23.248.2:5867 ESTABLISHED 14741/java
tcp6 2677 0 192.0.2.105:1988 221.130.33.37:15688 ESTABLISHED -
tcp6 3375 0 192.0.2.105:1988 221.130.33.36:3045 ESTABLISHED -
tcp6 14742 0 192.0.2.105:1988 46.23.248.17:4679 ESTABLISHED -
tcp6 774 0 192.0.2.105:1988 212.9.19.73:36064 ESTABLISHED -
tcp6 92 0 192.0.2.105:1988 46.23.248.19:7164 ESTABLISHED -
tcp6 0 0 192.0.2.105:1988 46.23.248.21:6322 ESTABLISHED 14741/java
tcp6 0 0 192.0.2.105:1988 221.130.39.216:13937 ESTABLISHED 14741/java
tcp6 3051 0 192.0.2.105:1988 211.139.145.104:31239 ESTABLISHED -
tcp6 246 0 192.0.2.105:1988 46.23.248.10:5458 ESTABLISHED -
tcp6 618 0 192.0.2.105:1988 212.9.19.73:20209 ESTABLISHED -
tcp6 1041 0 192.0.2.105:1988 46.23.248.18:7424 ESTABLISHED -
tcp6 0 0 192.0.2.105:1988 46.23.248.10:5065 ESTABLISHED 14741/java
Wenn dies geschieht und die Clients die Verbindung wiederherstellen, funktionieren sie normalerweise. Sie stellen die Verbindung jedoch nicht von selbst wieder her, bis ein ziemlich langes Timeout auftritt. Da das benutzerdefinierte Vollduplexprotokoll in seiner aktuellen Version keine vom Client gesendeten Daten bestätigt und dieser keine regelmäßig eingehenden Anfragen vom Server erwartet, kann es Tage dauern, bis der Client seine Daten problemlos sendet, bis die Empfangswarteschlange des Kernels voll ist. Auf der Server- (Kernel-)Seite sollte es möglich sein, veraltete Sockets zu erkennen, da die Clients regelmäßig Daten senden.
Vorausgesetzt, meine Interpretation dieses Problems ist richtig, habe ich mich gefragt, ob es einen Kernel-Parameter gibt, den ich anpassen kann, damit der Kernel TCP-Verbindungen mit einem RST trennt/schließt, wenn sie nicht rechtzeitig vom Benutzerbereich gelesen werden.
Bessere Erklärungen dessen, was hier passiert, sind ebenfalls willkommen.
Antwort1
Sie können versuchen, zu tunenTCP-Keepaliveauf viel kürzere Werte. Standardmäßig kann eine Verbindung zwei Stunden lang inaktiv sein, bevor Keepalive einsetzt.
Welche Werte Sie genau verwenden sollten, hängt wirklich davon ab, was Ihre Anwendung macht und was Ihre Benutzer erwarten oder wie sie mit ihr interagieren.
Antwort2
Ich denke, die Antwort ist nein.
Das Problem wurde durch den Austausch der betreffenden Software gelöst, Ideen sind jedoch weiterhin willkommen.