禁用 keepalive 时 io.Copy 超时

2024年 2月 14日 65.3k 0

禁用 keepalive 时 io.copy 超时

php小编鱼仔今天给大家介绍一个关于"禁用 keepalive 时 io.Copy 超时"的问题。在使用Go语言中的io.Copy函数进行数据传输时,如果禁用了keepalive,可能会导致传输超时的问题。这个问题可能会给开发者带来一些困扰,因此我们需要了解一些解决方法来避免这个问题的发生。下面就让我们一起来看看如何解决这个问题吧!

问题内容

当我禁用 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.Copy 将返回“splice: 连接超时”

如果我启用 keepalive

sudo sysctl -w net.ipv4.tcp_keepalive_probes=3

登录后复制

io.Copy就可以了

我尝试tcp客户端以1秒的间隔发送数据包并禁用tcp_keepalive,也可以。

我编写了另一个代码来代替 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()

登录后复制

15秒后读取超时,30秒不工作

为什么会这样,太奇怪了?

解决方法

答案:
当“kernel tcp stack”使用keepalive检测网络时,当“kernel tcp stack”需要发送keepalive时,net.ipv4.tcp_keepalive_probes = 0将会超时

以上就是禁用 keepalive 时 io.Copy 超时的详细内容,更多请关注每日运维网(www.mryunwei.com)其它相关文章!

相关文章

JavaScript2024新功能:Object.groupBy、正则表达式v标志
PHP trim 函数对多字节字符的使用和限制
新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
为React 19做准备:WordPress 6.6用户指南
如何删除WordPress中的所有评论

发布评论