Mac OS XのMDNSマルチキャストアドレスにバインドします
質問
マルチキャストDNSグループにバインドして、Mac OS Xマシンにポートして、いくつかのBonjour機能をプロトタイプにしたいと考えています。ただし、ポートにバインドしようとすると、次のエラーが表示されます(偶然にはPythonから実行されます)。
socket.error: [Errno 48] Address already in use
MDNSResponderがアドレスにバインドするように見えます:so_reuseaddrが解決したポート。
他のエージェントがアドレスにバインドできる方法でMDNSResponderを実行することは可能ですか:ポートの組み合わせ?
解決
エラーコードの説明は、この状況では少し混乱する可能性があります。 SO_REUSEPORTオプションを設定せずにアプリケーションがポートにバインドすると、2番目のアプリケーションが同じポートにバインドしようとすると、バインドは上記のエラーで失敗します。問題は、バインディングアドレスではなく、ポートとSO_REUSEPORTフラグにあります。
余談ですが、Linuxの下では、So_ReuseadDRフラグを使用することにより、同等の(複数のマルチキャストリスナー)機能が達成されます( Linuxのso_reuseport).
最初のアプリケーションは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インスタンスに登録されているため、Bonjourを使用するアプリケーションを再起動する必要がある場合があります。