Maison  >  Article  >  développement back-end  >  Délai d'expiration io.Copy lorsque keepalive est désactivé

Délai d'expiration io.Copy lorsque keepalive est désactivé

PHPz
PHPzavant
2024-02-13 21:36:081157parcourir

禁用 keepalive 时 io.Copy 超时

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 !

Contenu de la question

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 ?

Solution

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!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer