【问题标题】:Can't listen on IPv4 and IPv6 together (address already in use)无法同时监听 IPv4 和 IPv6(地址已在使用中)
【发布时间】:2018-05-07 06:51:08
【问题描述】:

我认为精确的代码并不重要。相反,我将给出 strace 输出:

socket(AF_INET, SOCK_STREAM, IPPROTO_IP) = 5
fcntl(5, F_SETFL, O_WRONLY|O_NONBLOCK)  = 0
epoll_ctl(3, EPOLL_CTL_ADD, 5, {EPOLLIN|EPOLLOUT|EPOLLRDHUP|EPOLLET, {u32=209357450, u64=94373525752458}}) = 0
setsockopt(5, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
bind(5, {sa_family=AF_INET, sin_port=htons(31337), sin_addr=inet_addr("0.0.0.0")}, 16) = 0
listen(5, 10)                           = 0
accept(5, 0x7f2a6aade440, [110])        = -1 EAGAIN (Resource temporarily unavailable)
stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2265, ...}) = 0
stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2265, ...}) = 0
stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2265, ...}) = 0
stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2265, ...}) = 0
write(1, "\33[1;30m09:44:34.625\33[0m\342\224\202\33[36m0"..., 130) = 130
socket(AF_INET6, SOCK_STREAM, IPPROTO_IP) = 6
fcntl(6, F_SETFL, O_WRONLY|O_NONBLOCK)  = 0
epoll_ctl(3, EPOLL_CTL_ADD, 6, {EPOLLIN|EPOLLOUT|EPOLLRDHUP|EPOLLET, {u32=209357482, u64=94373525752490}}) = 0
setsockopt(6, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
bind(6, {sa_family=AF_INET6, sin6_port=htons(31337), inet_pton(AF_INET6, "::", &sin6_addr), sin6_flowinfo=htonl(0), sin6_scope_id=0}, 28) = -1 EADDRINUSE (Address already in use)

我们可以看到套接字 5 (IPv4) 成功绑定到端口 any:31337,但是当我尝试绑定套接字 6 (IPv6) 时,它失败并显示 EADDRINUSE

您还可以看到我确实在两个套接字上都设置了SO_REUSEADDR,所以我相信这个问题不应该发生。

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 17.10
Release:        17.10
Codename:       artful

【问题讨论】:

  • 您是否尝试在同一个端口上侦听两次,一次使用 IPv4,一次使用 IPv6?这应该不是必需的,因为监听 IPv6 也应该监听 IPv4,地址显示为 ::FFFF:192.168.1.1
  • 是的,就是这样。如果您希望我接受,请用短语作为答案。

标签: linux sockets


【解决方案1】:

您不需要同时监听 IPv4 和 IPv6,因为监听 IPv6 连接就足够了。传入的 IPv4 连接将由 IPv6 连接的套接字列表处理。客户端地址可能会以::FFFF:192.168.1.1 这样的格式显示。

【讨论】:

  • 如果 OP 希望做不同的事情,还有一个系统范围的旋钮 (/proc/sys/net/conf/ipv6/bindv6only) 以及每个套接字的 setsockopt (IPV6_V6ONLY)
猜你喜欢
  • 2016-09-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-23
  • 2023-04-01
  • 1970-01-01
  • 2017-09-04
  • 1970-01-01
相关资源
最近更新 更多