gpt4 book ai didi

go - 关于套接字的 SO_REUSEADDR 不能在 golang 中正常工作吗?

转载 作者:IT王子 更新时间:2023-10-29 01:43:56 28 4
gpt4 key购买 nike

单个 IP 只能支持 65535 端口到单个目的地。 希望client在性能测试的时候能够立即重用旧的tcp_session,即使session还处于time_wait状态。

在我的 Linux 机器上,我打开了这些开关

sysctl -w net.ipv4.tcp_timestamps=1
sysctl -w net.ipv4.tcp_tw_recycle=1
sysctl -w net.ipv4.tcp_tw_reuse=1

然后我写了下面的代码来用golang验证socket_reuse选项。在代码中,我绑定(bind)了本地端口12345。

先跑后

$go run 1.go

$netstat -nat | grep 12345
tcp 0 0 192.168.1.11:12345 111.161.3.173:80 TIME_WAIT

中学之后

$go run 1.go
Client Connect() called error: cannot assign requested address

SO_REUSEADDR 好像不行。任何人都可以帮助解决这个问题吗?

package main

import (
"fmt"
. "syscall"
)

func main() {
var (
clientsock int
serveraddr SockaddrInet4
err error
)

if clientsock, err = Socket(AF_INET, SOCK_STREAM, IPPROTO_IP); err != nil {
fmt.Println("Client Socket() called error:", err.Error())
return
}
SetsockoptInt(clientsock, SOL_SOCKET, SO_REUSEADDR, 1)

defer Shutdown(clientsock, SHUT_RDWR)

serveraddr.Addr = [4]byte{111, 161, 3, 173}
serveraddr.Port = 80

err = Bind(clientsock, &SockaddrInet4{
Port: 12345,
})

if err = Connect(clientsock, &serveraddr); err != nil {
fmt.Println("Client Connect() called error:", err.Error())
return
}
}

最佳答案

您应该对代码添加两处更改:

1) 设置套接字选项 unix.SO_REUSEPORT。

if errReusePort := SetsockoptInt(clientsock, SOL_SOCKET, unix.SO_REUSEPORT, 1); errReusePort != nil {
fmt.Printf("reuse port error: %v\n", errReusePort)
return
}

2) 让您的代码连接到不同的远程 TCP 端点。否则,由于单一源地址/端口,TCP 将无法区分两个相同的连接(协议(protocol)、src-addr、src-port、dst-addr、dst-port)。下面的示例在命令行中指定了两个远程服务器地址。

$ go run main.go 127.0.0.1
connected

$ go run main.go 127.0.0.2
connected

在 Playground 上找到完整的工作代码:https://play.golang.org/p/HYLkWlVH6T4

关于go - 关于套接字的 SO_REUSEADDR 不能在 golang 中正常工作吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53868546/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com