Bind to mdns multicast address on mac os x
I want to bind to the multicast DNS group and port on a mac os x machine to prototype some bonjour functionality. However, when I try to bind to the port I get the following error (incidentally this is run from python):
socket.error: [Errno 48] Address already in use
It looks like the mDNSResponder binds to the address:port with SO_REUSEADDR unset.
Is it possible to run the mDNSResponder in a way that lets other agents bind to the address:port combina开发者_开发技巧tion?
The error code description may be a little confusing in this situation. When an application binds to a port without setting the SO_REUSEPORT option, if a second application tries to bind to the same port the bind will fail with the above error. The problem is not with the binding address though, but with the port and the SO_REUSEPORT flag.
As an aside, under linux the equivalent (multiple multicast listeners) functionality is achieved by using the SO_REUSEADDR flag (as per SO_REUSEPORT on linux).
The first application has to bind with the SO_REUSEPORT flag set, otherwise it will have an exclusive bind and other application binds will fail. For example:
# For BSD based platforms.
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
sock.bind(('', MCAST_PORT))
It turns out that the mDNSResponder can start with the SO_REUSEPORT flag set, but only if it fails to bind exclusively when the service is started. You can do the following to make it go into this mode:
- Shutdown the mDNSResponder service (more info here)
- Bind to the address:port with your application using SO_REUSEPORT
- Restart the mDNSResponder service
The mDNSResponder service will start and bind using the SO_REUSEPORT flag. Other applications can then share the port until the next reboot. You may need to restart any applications that use bonjour as they will have been registered to the old mDNSResponder instance.
精彩评论