Go语言 io.禁用keepalive时复制超时

pb3skfrl  于 2023-11-14  发布在  Go
关注(0)|答案(1)|浏览(141)

当我禁用Linux keepalive时,

sudo sysctl -w net.ipv4.tcp_keepalive_probes=0

字符串
并运行以下代码

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.复制将返回“拼接:连接超时”
如果启用keepalive,

sudo sysctl -w net.ipv4.tcp_keepalive_probes=3


io.复制就可以了
我尝试tcp客户端以1秒的间隔发送数据包,并禁用tcp_keepalive,它也可以。
我写另一段代码来代替io,收到

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()


15秒后读超时,30秒后不工作
为什么会这样,太奇怪了吧?

ojsjcaue

ojsjcaue1#

主持人:当“内核tcp堆栈”使用keepalive检测网络时,当“内核tcp堆栈”需要发送keepalive时,net.ipv4.tcp_keepalive_probes = 0将超时

相关问题