POSIX Bonjour/mDNSResponder 测试示例在 Ubuntu 上报告 "bind: Address already in use",但不是 Debian
POSIX Bonjour/mDNSResponder test examples report "bind: Address already in use" on Ubuntu, but not Debian
在构建 Apple 的 mDNS 实现时,又名。 Bonjour,又名。 posix 系统的 mDNSResponder (http://www.opensource.apple.com/tarballs/mDNSResponder/) [*]
在一个干净的 Ubuntu 14.04
build box(只有 build-essentials, g++
)上,编译的示例 无法工作 ,并报告 "bind: Address already in use"
.
在一个干净的 Debian 7
build box(只有 build-essentials, g++
)上,编译的示例 work,和 不要举报"bind: Address already in use"
.
这是怎么回事?
[*] 这...只是充满了错误。为了理智,我建议使用版本 333.10 或 541,并应用来自 umondo 项目的补丁:https://github.com/tklab-tud/umundo/tree/master/contrib/archives
问题是由于 /usr/include/asm-generic/socket.h
中的以下差异造成的
有问题的 socket.h
是 linux-libc-dev
包的一部分。
在 Debian
中,socket.h
来自 linux-libc-dev
的版本 3.2.65
,并且包含注释行
/* To add :#define SO_REUSEPORT 15 */
在 Ubuntu
上,linux-libc-dev
是版本 3.13.0
。 socket.h
。在这里,该行不再被注释掉:
#define SO_REUSEPORT 15
当然,问题不在于 linux-libc-dev
,而是在 mDNSPosix.c
中使用此宏,特别是行:
#if defined(SO_REUSEPORT)
err = setsockopt(*sktPtr, SOL_SOCKET, SO_REUSEPORT, &kOn, sizeof(kOn));
#elif defined(SO_REUSEADDR)
err = setsockopt(*sktPtr, SOL_SOCKET, SO_REUSEADDR, &kOn, sizeof(kOn));
#else
#error This platform has no way to avoid address busy errors on multicast.
#endif
通过交换顺序,确定优先级 SO_REUSEADDR
,不再存在套接字绑定问题。即:
#if defined(SO_REUSEADDR)
err = setsockopt(*sktPtr, SOL_SOCKET, SO_REUSEADDR, &kOn, sizeof(kOn));
#elif defined(SO_REUSEPORT)
err = setsockopt(*sktPtr, SOL_SOCKET, SO_REUSEPORT, &kOn, sizeof(kOn));
#else
#error This platform has no way to avoid address busy errors on multicast.
#endif
注意:此更改尚未在 BSD
中进行测试,如果我理解正确,可能应该保持优先级不变。
您正在 运行 了解 SO_REUSEADDR 和 SO_REUSEPORT 之间的差异。
SO_REUSEPORT 是在后来的 Linux 内核中引入的,Ubuntu 系统映像似乎支持它。查看 this 问题,了解您可能想知道的关于 REUSADDR/REUSEPORT.
的所有信息
REUSEADDR 和 REUSEPORT 之间的行为差异在于 REUSEPORT 对尝试重用同一端口的套接字施加了更多限制:它们都必须设置选项并存在于同一进程中。 REUSEADDR 不是这种情况。
是否有可能您的 Ubuntu 图像也 运行 正在使用另一个像 avahi 这样的 mDNS 守护进程?您可以运行 netstat 诊断系统中其他绑定的套接字以识别端口冲突
在构建 Apple 的 mDNS 实现时,又名。 Bonjour,又名。 posix 系统的 mDNSResponder (http://www.opensource.apple.com/tarballs/mDNSResponder/) [*]
在一个干净的
Ubuntu 14.04
build box(只有build-essentials, g++
)上,编译的示例 无法工作 ,并报告"bind: Address already in use"
.在一个干净的
Debian 7
build box(只有build-essentials, g++
)上,编译的示例 work,和 不要举报"bind: Address already in use"
.
这是怎么回事?
[*] 这...只是充满了错误。为了理智,我建议使用版本 333.10 或 541,并应用来自 umondo 项目的补丁:https://github.com/tklab-tud/umundo/tree/master/contrib/archives
问题是由于 /usr/include/asm-generic/socket.h
有问题的 socket.h
是 linux-libc-dev
包的一部分。
在 Debian
中,socket.h
来自 linux-libc-dev
的版本 3.2.65
,并且包含注释行
/* To add :#define SO_REUSEPORT 15 */
在 Ubuntu
上,linux-libc-dev
是版本 3.13.0
。 socket.h
。在这里,该行不再被注释掉:
#define SO_REUSEPORT 15
当然,问题不在于 linux-libc-dev
,而是在 mDNSPosix.c
中使用此宏,特别是行:
#if defined(SO_REUSEPORT)
err = setsockopt(*sktPtr, SOL_SOCKET, SO_REUSEPORT, &kOn, sizeof(kOn));
#elif defined(SO_REUSEADDR)
err = setsockopt(*sktPtr, SOL_SOCKET, SO_REUSEADDR, &kOn, sizeof(kOn));
#else
#error This platform has no way to avoid address busy errors on multicast.
#endif
通过交换顺序,确定优先级 SO_REUSEADDR
,不再存在套接字绑定问题。即:
#if defined(SO_REUSEADDR)
err = setsockopt(*sktPtr, SOL_SOCKET, SO_REUSEADDR, &kOn, sizeof(kOn));
#elif defined(SO_REUSEPORT)
err = setsockopt(*sktPtr, SOL_SOCKET, SO_REUSEPORT, &kOn, sizeof(kOn));
#else
#error This platform has no way to avoid address busy errors on multicast.
#endif
注意:此更改尚未在 BSD
中进行测试,如果我理解正确,可能应该保持优先级不变。
您正在 运行 了解 SO_REUSEADDR 和 SO_REUSEPORT 之间的差异。
SO_REUSEPORT 是在后来的 Linux 内核中引入的,Ubuntu 系统映像似乎支持它。查看 this 问题,了解您可能想知道的关于 REUSADDR/REUSEPORT.
的所有信息REUSEADDR 和 REUSEPORT 之间的行为差异在于 REUSEPORT 对尝试重用同一端口的套接字施加了更多限制:它们都必须设置选项并存在于同一进程中。 REUSEADDR 不是这种情况。
是否有可能您的 Ubuntu 图像也 运行 正在使用另一个像 avahi 这样的 mDNS 守护进程?您可以运行 netstat 诊断系统中其他绑定的套接字以识别端口冲突