在macOS上绑定mdns多播地址
我想在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标志的情况下启动,但前提是它在服务启动时无法独占绑定。你可以按照以下步骤让它进入这种模式:
- 关闭mDNSResponder服务(更多信息在这里)
- 使用你的应用程序通过SO_REUSEPORT绑定到地址和端口
- 重新启动mDNSResponder服务
这样,mDNSResponder服务就会启动并使用SO_REUSEPORT标志进行绑定。其他应用程序可以共享这个端口,直到下次重启。你可能需要重新启动任何使用Bonjour的应用程序,因为它们会注册到旧的mDNSResponder实例上。