如何在 Linux 中调试 TCP 套接字创建?

How do you debug TCP socket creation in Linux?

提问人:William John Holden 提问时间:10/3/2023 更新时间:10/3/2023 访问量:122

问:

我正在为计算机网络的硕士项目开发一个特定于 Linux 的 Go 应用程序。我的应用程序快速将新的 IPv6 地址添加到 NIC,并从这些地址创建 TCP 套接字。此操作经常失败,但有时有效。当它失败时,Go 中的错误消息是模糊的。我看不出有什么用处.dmesgstrace

以下是相关代码的一部分:

src, err = net.ResolveTCPAddr("tcp6", net.JoinHostPort(address.IP.String(), "0"))
if err != nil {
    return err
}

// (Some irrelevant lines omitted. I do not think that the tcp6/tcp mismatch is the problem.)

dst, err = net.ResolveTCPAddr("tcp", net.JoinHostPort(ip.String(), strconv.Itoa(port)))
if err != nil {
    return err
}

server_conn, err := net.DialTCP("tcp", src, dst) // (This is where the problem happens.)
if err != nil {
    return err
}
defer server_conn.Close()

Go 中的 in 如下所示:error

dial tcp [2001::xxxx]:0->[2a03:2880:f036:1d:face:b00c:0:3]:443: bind: cannot assign requested address

在哪里可以查找有关失败原因的更多详细信息? 我在 Internet 上发现了类似错误的讨论,其中其他应用程序指定了使用的源地址,但我还没有学到一个好的调试方法。DialTCPbind

Linux Go 套接字网络 TCP

评论

4赞 kostix 10/3/2023
(通常使用软件包安装)是否显示该地址在主机的某个接口上确实可用?该错误基本上意味着系统无法绑定本地套接字。通常的情况是,您的系统不“拥有”列出的 IP 地址,因此它自然不能使用它来发送或接收 IP 数据包。ip addriproute2[2001::xxxx]
0赞 William John Holden 10/3/2023
它应该,但这是一个好主意 - 我将编写一个验证函数来检查该地址是否在任何链接上可用。src
1赞 kostix 10/3/2023
[1/2] 还有另一种可能的情况:所谓的临时端口耗尽:当你要求系统绑定到端口 0 时,它应该从配置的池中选择一个空闲的端口(使用;是的,IPv6 也使用它)。当 TCP 连接关闭时,堆栈会将其本地端口保留一段时间,以等待可能在传输过程中延迟的重复和无序数据包。当您以高速率进行大量短期连接时,舀起整个范围并陷入没有自由端口的情况并不少见。/sbin/sysctl net.ipv4.ip_local_port_range
1赞 kostix 10/3/2023
[2/2] 要检查这一点,请使用或类似的工具。有关详细信息,请参阅此处ss state time-wait
2赞 dimich 10/3/2023
如果失败,strace 输出应包含值。跑。实际上无法分配请求的地址是 EADDRNOTAVAIL 的简单消息:请求了不存在的接口或请求的地址不是本地的。由于缺少临时端口,errno 应为 .errnobind()strace -e bind ...EADDRINUSE

答: 暂无答案