0

在构建 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++)上,编译的示例可以工作,并且报告"bind: Address already in use".

这里发生了什么?

[*] 这...只是充满了错误。为了理智,我建议使用 333.10 或 541 版本,并应用 umondo 项目中的补丁:https ://github.com/tklab-tud/umundo/tree/master/contrib/archives

4

2 回答 2

0

问题是由于以下差异造成的/usr/include/asm-generic/socket.h

socket.h问题的是linux-libc-dev 包装的一部分。

Debian,socket.h来自 的版本3.2.65, linux-libc-devcontains 包含注释行

/* To add :#define SO_REUSEPORT 15 */

Ubuntulinux-libc-dev是版本3.13.0socket.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,不再存在套接字绑定问题。IE:

#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,如果我理解正确,可能应该保持优先级的顺序。

于 2015-02-27T07:54:04.207 回答
0

您遇到了 SO_REUSEADDR 和 SO_REUSEPORT 之间的差异。

SO_REUSEPORT 是在后来的 Linux 内核中引入的,看来 Ubuntu 系统映像支持它。看看这个问题,你可能想知道关于 REUSADDR/REUSEPORT 的所有信息。

REUSEADDR 和 REUSEPORT 之间的行为差​​异在于 REUSEPORT 对尝试重用同一端口的套接字设置了更多限制:它们都必须设置选项并存在于同一进程中。REUSEADDR 并非如此。

您的 Ubuntu 映像是否可能也在运行另一个 mDNS 守护程序,例如 avahi?您可以运行 netstat 来诊断系统中的其他绑定套接字以识别端口冲突

于 2015-04-14T05:44:49.487 回答