Heim > Artikel > Backend-Entwicklung > Fehlerbericht zum Schließen von Golang TCP
Als ich kürzlich Golang zum Schreiben eines TCP-Kommunikationsprogramms verwendete, stieß ich auf einen seltsamen Fehler beim Schließen, den ich aufzeichnete und teilte.
Hintergrund
In dem von mir geschriebenen TCP-Kommunikationsprogramm habe ich das Net-Paket in der Go-Standardbibliothek verwendet, um über die DialTCP-Funktion eine Verbindung zum Server herzustellen. Verwenden Sie nach Abschluss der Kommunikation die Close-Methode, um die Verbindung zu schließen. In den meisten Fällen ist dieser Prozess erfolgreich. Aber manchmal wird beim Aufruf der Close-Methode ein seltsamer Fehler ausgegeben und das Programm stürzt ab.
Fehlerbeschreibung
- Fehler beim Close-TCP-Aufruf -
Beschreibung: Zurücksetzen durch Peer`
Das Fehlerprotokoll zeigt dies bei Verwendung von When Wenn die Close-Methode die Verbindung schließt, wird ein Fehler „reset by peer“ gemeldet, was bedeutet, dass der Server die Verbindung aktiv schließt.
Fehlerbehebung
Im ersten Schritt habe ich den Quellcode überprüft und bestätigt, dass die Verbindung nicht geschlossen wurde, bevor ich die Close-Methode aufgerufen habe. Im zweiten Schritt versuche ich, das Problem aus der Perspektive des Codes zu analysieren und dann die Fehler des Codes zu beseitigen.
Im dritten Schritt habe ich nach diesem Problem gesucht und ähnliche Fälle gefunden. In der Open-Source-Community Github sind viele Menschen auf ähnliche Probleme gestoßen. Einige Leute glauben, dass dies ein Problem mit der Implementierung der TCP-Spezifikation durch das Betriebssystem ist, und andere denken, dass es sich um einen Fehler im Netzwerkkartentreiber handelt. Nachdem ich diese Informationen gesehen hatte, überprüfte ich die Spezifikationen des TCP-Protokolls und stellte fest, dass es tatsächlich eine TIME_WAIT-Zeit gibt, um auf den Vorgang zum Schließen der Verbindung zu warten.
Insbesondere wartet das Betriebssystem nach dem Schließen einer TCP-Verbindung eine bestimmte Zeit, bis es bestätigt, dass die Verbindung vollständig geschlossen wurde, bevor es zugehörige Ressourcen freigibt. Diese Zeit beträgt normalerweise 2MSL (Maximum Segment Lifetime) und der Standardwert beträgt unter Linux 60 Sekunden. Wenn während dieser Wartezeit eine neue Verbindungsanforderung mit derselben Adresse und demselben Port vorliegt, wird das RST-Segment ausgelöst, dh die andere Partei schließt die Verbindung vorzeitig und es tritt ein Fehler „Reset by Peer“ auf.
Also, wie kann man dieses Problem lösen?
Lösung
Für dieses Problem gibt es zwei Lösungen:
Ändern Sie die Parameter des Linux-Kernels, um die TIME_WAIT-Zeit zu verlängern, um sicherzustellen, dass die Verbindung vollständig geschlossen wird. Natürlich steigt in diesem längeren Zeitraum auch die Anzahl der Verbindungen im System, die sich schon lange im Zustand TIME_WAIT befinden.
Aktivieren Sie beim Schließen der Verbindung die Option SO_REUSEADDR, um die Verbindungsadresse wiederverwendbar zu machen. Auf diese Weise kann nach dem Schließen der Verbindung die nächste neue Verbindung die ursprüngliche Adresse direkt wiederverwenden, wodurch Fehler beim „Zurücksetzen durch Peer“ vermieden werden. Die spezifische Implementierungsmethode lautet wie folgt:
conn, err := net.DialTCP("tcp", nil, tcpAddr) err = conn.SetReuseAddr(true) err = conn.Close()
Zusammenfassung
Das Obige ist ein Fall eines seltsamen Schließfehlers, auf den ich beim Schreiben eines TCP-Kommunikationsprogramms in Golang gestoßen bin. Der Grund dafür ist, dass die Verbindung aufgrund der in der TCP-Spezifikation geforderten TIME_WAIT-Zeit nicht sofort freigegeben wird. Durch Verlängern der Wartezeit oder Aktivieren der Option SO_REUSEADDR können wir diese Art von Fehler vermeiden. Gleichzeitig erinnert uns dies auch daran, dass wir bei der Netzwerkprogrammierung auf einige Details in der TCP-Spezifikation achten müssen, um unnötige Fehler zu vermeiden.
Das obige ist der detaillierte Inhalt vonFehlerbericht zum Schließen von Golang TCP. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!