【问题标题】:POSIX Bonjour/mDNSResponder test examples report "bind: Address already in use" on Ubuntu, but not DebianPOSIX Bonjour/mDNSResponder 测试示例在 Ubuntu 上报告“绑定:地址已在使用中”,但不是 Debian
【发布时间】:2015-02-27 07:54:04
【问题描述】:

在构建 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

【问题讨论】:

    标签: c sockets posix bonjour mdns


    【解决方案1】:

    问题是由于/usr/include/asm-generic/socket.h下面的不同

    有问题的socket.hlinux-libc-dev 包的一部分。

    Debian 中,socket.h 来自linux-libc-dev 的版本3.2.65,并且包含包含注释的行

    /* To add :#define SO_REUSEPORT 15 */
    

    Ubuntu 上,linux-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,就不再存在套接字绑定问题。即:

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

    【讨论】:

    • 我在这里添加这个的原因是这个问题,以及其他几个“这不可能通过编译”的错误(看着你mDNSShared/dnssd_clientshim.c),一直存在卓悦图书馆多年。令人怀疑错误报告是否会及时修复另一个此类错误。
    【解决方案2】:

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

    SO_REUSEPORT 是在后来的 Linux 内核中引入的,Ubuntu 系统映像似乎支持它。查看this 问题,了解有关 REUSADDR/REUSEPORT 的所有信息。

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

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

    【讨论】:

      猜你喜欢
      • 2018-02-21
      • 1970-01-01
      • 2011-10-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-27
      • 1970-01-01
      相关资源
      最近更新 更多