MonoのUDPは、制限ブロードキャストの受信に制約あり

これも個人的な調査結果です。

Windows/.NET(4.5)とLinux(Ubuntu16.04)/Mono(4.2.1)での通信を試していたのですが、どうもうまく動作しませんでした。調べた結果、次のようなことが明らかになりました。

  • Linux/Monoで、IPAddress.Anyにバインドした場合、ブロードキャスト通信は受信可能
  • Linux/Monoで、特定のIPアドレスにバインドした場合、ブロードキャスト通信は受信不可能
  • Windows/.NETでは、どちらのバインドでも、ブロードキャスト通信の受信は可能

これは同一環境、同一プログラムで、バインド先IPアドレスだけを変えることで再現します。

検索してみた結果、どうやらMonoのUDP通信は、自らのサブネット外から受信した場合は棄却し、受信処理が一切動かないらしいと判明しました。

mono.1490590.n4.nabble.com

実は、送信には制限ブロードキャストを使っていました(IPAddress.Broadcastで簡単に使えるのと、特にルータを超える必要がなかったので)。

制限ブロードキャストを受信するには、IPAddress.Any(0.0.0.0)にバインドする必要があるということで。

ちなみに、IPv4の(制限ではない)ブロードキャストアドレスを求めるためにはサブネットマスクが必要ですが、MonoのUnicastAddress.IPv4Maskプロパティは、長らく実装されておらず、NotImplementedExceptionだったようです。ようやくMono4.4.0(2016-06-08リリース)で実装されました。

https://bugzilla.xamarin.com/show_bug.cgi?id=2033bugzilla.xamarin.com

http://www.mono-project.com/docs/about-mono/releases/4.4.0/www.mono-project.com

2033 - UnicastAddress.IPv4Mask throws NotImplementedException on Mono 2.10 running on open-embedded Linux

※「open-embedded」とありますが、実際はBugZillaを読む限り「Win32以外の全てのプラットフォーム」のバグです。

github.com

Monoのソースを見る限り、UnicastIPAddressInformationクラスのプロパティの大半は、いまだに未実装ですね……。