当前位置: 首页 > 面试题库 >

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

孙承
2023-03-14
问题内容

单个IP仅支持65535端口到单个目标。我希望客户端即使在会话仍处于time_wait状态的情况下,也可以在性能测试期间立即重用旧的tcp_session。

在我的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选项。在代码中,我绑定了本地端口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将无法区分两个相同的连接(协议,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



 类似资料:
  • 我正试图在按下某个按钮时弹出一个警报对话框。我首先使用了Android Developer的示例代码而不是'这不起作用,所以我根据在这个站点上发现的情况进行了更改,但是现在我的程序在按下按钮后被迫停止。 就你的知识而言,这是在第二个不同于主要的活动中完成的。不确定这是否重要.... ‘ 碰撞日志:“03-25 19:34:24.373:E/AndroidRuntime(18828):致命异常:ma

  • 2,错误{org.apache.directory.server.LDAP.ldapserver}-ERR_171无法将LDAP服务(10,389)绑定到服务注册表。java.net.BindException:已在使用的地址 请帮忙谢谢 --------提示------------------- JAVA_HOME环境变量设置为/opt/java CARBON_HOME环境变量设置为/mnt/1

  • 我正在处理碎片,所以在我的视图寻呼机中有三个碎片 因此,我在第一个片段中使用了方法,所以当我从一个片段切换到另一个片段并返回到第一个片段时,我的方法不起作用 所以有人给出解决方案吗

  • 这是通过递归和回溯解决的一个经典问题,使用下面的Java代码: } }

  • 问题内容: 我希望能够停止在Linux中的服务器套接字上进行侦听,并确保正确处理了从客户端角度打开的所有连接,并且没有突然关闭它们(即:接收ECONNRESET)。 即: 如果认为调用close()并处理已经接受的套接字就足够了,但是可以在内核积压中打开一些连接,如果在服务器套接字上调用close(),这些连接将突然关闭。 问题答案: 唯一可行的方法(我发现)是: 阻止添加更多客户端 在某处有一个

  • 本文向大家介绍详谈套接字中SO_REUSEPORT和SO_REUSEADDR的区别,包括了详谈套接字中SO_REUSEPORT和SO_REUSEADDR的区别的使用技巧和注意事项,需要的朋友参考一下 Socket的基本背景 在讨论这两个选项的区别时,我们需要知道的是BSD实现是所有socket实现的起源。基本上其他所有的系统某种程度上都参考了BSD socket实现(或者至少是其接口),然后开始了