php-Editor Yuzai stellt Ihnen heute ein Problem zum Thema „io.Copy-Timeout, wenn Keepalive deaktiviert ist“ vor. Wenn Sie die io.Copy-Funktion in der Go-Sprache für die Datenübertragung verwenden und Keepalive deaktiviert ist, kann es zu einer Zeitüberschreitung bei der Übertragung kommen. Dieses Problem kann den Entwicklern einige Probleme bereiten, daher müssen wir einige Lösungen kennen, um das Auftreten dieses Problems zu vermeiden. Werfen wir einen Blick darauf, wie wir dieses Problem lösen können!
Wenn ich Linux Keepalive deaktiviere
sudo sysctl -w net.ipv4.tcp_keepalive_probes=0
Und führen Sie den folgenden Code aus
package main import ( "fmt" "io" "net" "os" "sync" "time" ) func main() { go func() { listen, err := net.Listen("tcp", "127.0.0.1:9390") if err != nil { fmt.Printf("net listen fail, reason: [%s]\n", err.Error()) os.Exit(1) } defer listen.Close() for { conn, err := listen.Accept() if err != nil { fmt.Printf("net accept fail, reason: [%s]\n", err.Error()) continue } _, err = io.Copy(conn, conn) if err != nil { fmt.Printf("net Copy fail, reason: [%s]\n", err.Error()) continue } conn.Close() } }() var wg sync.WaitGroup wg.Add(1) go func() { defer wg.Done() for { time.Sleep(1 * time.Second) tcpAddr, _ := net.ResolveTCPAddr("tcp", "127.0.0.1:9390") fmt.Println("tcp client resolve success: ", tcpAddr.String()) tcpConn, err := net.DialTCP("tcp", nil, tcpAddr) if err != nil { fmt.Println("tcp connect fail: ", err.Error()) return } time.Sleep(100 * time.Second) tcpConn.Close() fmt.Println("tcp end") } }() wg.Wait() }
io.Copy gibt „splice: Verbindungszeitüberschreitung“ zurück
Wenn ich Keepalive aktiviere
sudo sysctl -w net.ipv4.tcp_keepalive_probes=3
io.Copy ist genug
Ich habe versucht, mit dem TCP-Client Pakete im 1-Sekunden-Intervall zu senden und tcp_keepalive deaktiviert, das hat auch funktioniert.
Ich habe einen anderen Code geschrieben, um io.Copy zu ersetzen
buf := make([]byte, 10) for { conn.SetReadDeadline(time.Now().Add(30 * time.Second)) n, err := conn.Read(buf) if err != nil { fmt.Println("read fail: ", err.Error()) break } _, err = conn.Write(buf[:n]) if err != nil { fmt.Println("write fail: ", err.Error()) break } } conn.Close()
Lese-Timeout nach 15 Sekunden, funktioniert 30 Sekunden lang nicht
Warum passiert das so seltsam?
Antwort: Wenn der „Kernel-TCP-Stack“ Keepalive verwendet, um das Netzwerk zu erkennen, und der „Kernel-TCP-Stack“ Keepalive senden muss, tritt bei net.ipv4.tcp_keepalive_probes = 0 eine Zeitüberschreitung auf
Das obige ist der detaillierte Inhalt vonio.Copy-Timeout, wenn Keepalive deaktiviert ist. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!