在macOS上绑定mdns多播地址

2 投票
1 回答
2873 浏览
提问于 2025-04-17 01:45

我想在Mac OS X机器上绑定到多播DNS组和端口,以便原型开发一些Bonjour功能。但是,当我尝试绑定到这个端口时,出现了以下错误(顺便说一下,这是在Python中运行的):

socket.error: [Errno 48] Address already in use

看起来mDNSResponder在没有设置SO_REUSEADDR的情况下绑定了这个地址和端口。

有没有可能以某种方式运行mDNSResponder,让其他程序也能绑定到这个地址和端口组合呢?

1 个回答

5

在这种情况下,错误代码的描述可能会让人感到困惑。当一个应用程序试图绑定到一个端口,但没有设置SO_REUSEPORT选项时,如果第二个应用程序也想绑定到同一个端口,就会出现绑定失败的错误。问题不在于绑定的地址,而是在于端口和SO_REUSEPORT这个标志。

顺便提一下,在Linux系统中,类似的功能(多个多播监听器)是通过使用SO_REUSEADDR标志来实现的(具体可以参考SO_REUSEPORT在Linux上的使用)。

第一个应用程序必须在设置了SO_REUSEPORT标志的情况下进行绑定,否则它将独占这个端口,其他应用程序的绑定请求就会失败。例如:

# For BSD based platforms.
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
sock.bind(('', MCAST_PORT))

结果发现,mDNSResponder可以在设置了SO_REUSEPORT标志的情况下启动,但前提是它在服务启动时无法独占绑定。你可以按照以下步骤让它进入这种模式:

  1. 关闭mDNSResponder服务(更多信息在这里
  2. 使用你的应用程序通过SO_REUSEPORT绑定到地址和端口
  3. 重新启动mDNSResponder服务

这样,mDNSResponder服务就会启动并使用SO_REUSEPORT标志进行绑定。其他应用程序可以共享这个端口,直到下次重启。你可能需要重新启动任何使用Bonjour的应用程序,因为它们会注册到旧的mDNSResponder实例上。

撰写回答