为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
九州编程 2023-05-22 15:38:54
单个 IP 只能支持 65535 端口到单个目标。希望client在性能测试的时候能够立即重用旧的tcp_session,即使session还处于time_wait状态。在我的 Linux 机器上,我打开了这些开关sysctl -w net.ipv4.tcp_timestamps=1sysctl -w net.ipv4.tcp_tw_recycle=1sysctl -w net.ipv4.tcp_tw_reuse=1然后我写了下面的代码来用golang验证socket_reuse选项。在代码中,我绑定了本地端口12345。先跑后$go run 1.go$netstat -nat | grep 12345tcp        0      0 192.168.1.11:12345         111.161.3.173:80            TIME_WAIT二次运行后$go run 1.goClient Connect() called error: cannot assign requested address似乎 SO_REUSEADDR 不能工作。任何人都可以帮助解决这个问题吗?package mainimport (    "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 回答

?
慕田峪9158850

TA贡献1794条经验 获得超7个赞

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


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 将无法区分两个相同的连接(协议、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

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


查看完整回答
反对 回复 2023-05-22
  • 1 回答
  • 0 关注
  • 161 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信