L'éditeur php Yuzai vous présentera aujourd'hui un problème concernant le "délai d'expiration io.Copy lorsque keepalive est désactivé". Lors de l'utilisation de la fonction io.Copy dans la langue Go pour la transmission de données, si keepalive est désactivé, un délai d'attente de transmission peut se produire. Ce problème peut causer des problèmes aux développeurs, nous devons donc connaître quelques solutions pour éviter que ce problème ne se produise. Voyons comment résoudre ce problème !
Quand je désactive Linux Keepalive
sudo sysctl -w net.ipv4.tcp_keepalive_probes=0
Et exécutez le code suivant
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 renverra "splice: connection timeout"
Si j'active keepalive
sudo sysctl -w net.ipv4.tcp_keepalive_probes=3
io.La copie suffit
J'ai essayé le client TCP pour envoyer des paquets à 1 seconde d'intervalle et j'ai désactivé tcp_keepalive, cela a également fonctionné.
J'ai écrit un autre code pour remplacer io.Copy
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()
Délai de lecture après 15 secondes, ne fonctionne pas pendant 30 secondes
Pourquoi cela arrive-t-il ? C'est si bizarre ?
Réponse : Lorsque la « pile TCP du noyau » utilise keepalive pour détecter le réseau, lorsque la « pile TCP du noyau » doit envoyer keepalive, net.ipv4.tcp_keepalive_probes = 0 expirera
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!