Heim  >  Artikel  >  Backend-Entwicklung  >  io.Copy-Timeout, wenn Keepalive deaktiviert ist

io.Copy-Timeout, wenn Keepalive deaktiviert ist

PHPz
PHPznach vorne
2024-02-13 21:36:081157Durchsuche

禁用 keepalive 时 io.Copy 超时

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!

Frageninhalt

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?

Lösung

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!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen