在构建Apple的mDNS实现时,又名。 Bonjour,又名。 posix系统的mDNSResponder(http://www.opensource.apple.com/tarballs/mDNSResponder/)[*]
在干净的Ubuntu 14.04
构建框(仅包含build-essentials, g++
)上,已编译的示例无法正常工作,并报告"bind: Address already in use"
。
在干净的Debian 7
构建框(仅包含build-essentials, g++
)上,已编译的示例工作,而不报告{ {1}}。
这里发生了什么?
[*] ......只是充满了虫子。为了理智,我建议使用版本333.10或541,并应用umondo项目中的补丁:https://github.com/tklab-tud/umundo/tree/master/contrib/archives
答案 0 :(得分:0)
问题是由于/usr/include/asm-generic/socket.h
有问题的socket.h
是linux-libc-dev
包的一部分。
在Debian
中,socket.h
来自3.2.65
的{{1}}版本,其中包含注释行
linux-libc-dev
在/* 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
中进行测试,如果我理解正确的话,可能应按优先顺序保留优先级。
答案 1 :(得分:0)
您正在遇到SO_REUSEADDR和SO_REUSEPORT之间的差异。
SO_REUSEPORT是在后来的Linux内核中引入的,看来Ubuntu系统映像支持它。查看this问题,了解有关REUSADDR / REUSEPORT的所有信息。
REUSEADDR和REUSEPORT之间的行为差异是REUSEPORT对尝试重用相同端口的套接字施加了更多限制:它们都必须设置选项并存在于同一进程中。 REUSEADDR的情况并非如此。
你的Ubuntu镜像是否也可以运行像avahi这样的另一个mDNS守护进程?您可以运行netstat来诊断系统中的其他绑定套接字以识别端口冲突