複数ネットワーク環境の場合のC#のUDP通信は送信元IPをあわせる必要がある。

掲載日

前提

  • NIC2枚以上刺し。(LAN口から線が二つ以上出ている。)
  • そこから繋がってる端末にSendMagicPacket送ったりしたい。
  • Windows
  • C#

結論

以下のような状態になっているとします。

  • ネットワーク1に繋がっているLANのアドレスが192.168.1.10
  • ネットワーク1の中に端末Aがおり、その端末のアドレスは192.168.1.20
  • ネットワーク2に繋がっているLANのアドレスが192.168.2.10
  • ネットワーク2の中に端末Bがおり、その端末のアドレスは192.168.2.20

 

192.168.1.20端末を起動するなら以下のようにします。

IPEndPoint fromEp = new IPEndPoint(IPAddress.Parse(192.168.1.10), port);
 // ここが192.168.1.20と同じネットワーク側のIPである必要がある
UdpClient udp = new UdpClient(fromEp);

// SendMagicPacket処理など
mac_addr = "XXX"; // 192.168.1.20のMacアドレス
Byte[] magicPacket = new Byte[6 * 17];

Array.Copy(new Byte[] { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, magicPacket, 6);
for (int n = 0; n < 16; n++)
{
   Array.Copy(mac_addr, 0, magicPacket, 6 + 6 * n, 6);
}
udp.Send(magicPacket, magicPacket.Length, new IPEndPoint(IPAddress.Broadcast, 0));

192.168.2.20端末を起動するなら以下のようにします。

IPEndPoint fromEp = new IPEndPoint(IPAddress.Parse(192.168.2.10), port);
 // ここが192.168.2.20と同じネットワーク側のIPである必要がある
UdpClient udp = new UdpClient(fromEp);

// SendMagicPacket処理など
mac_addr = "XXX"; // 192.168.2.20のMacアドレス
Byte[] magicPacket = new Byte[6 * 17];

Array.Copy(new Byte[] { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, magicPacket, 6);
for (int n = 0; n < 16; n++)
{
   Array.Copy(mac_addr, 0, magicPacket, 6 + 6 * n, 6);
}
udp.Send(magicPacket, magicPacket.Length, new IPEndPoint(IPAddress.Broadcast, 0));

事象と原因

一つの端末で複数のネットワークを見に行っている図。

よくあるお仕事として、セキュリティのためにネットワークを分けていることがあります。
(一般利用者が使用する端末の所属するネットワーク1と、職員が利用する端末の所属するネットワーク2があり、どちらにもつながる管理用の端末Aがある等。)

管理端末は施設の開館などにあわせてどちらの端末にもSendMagicPacketを送出して電源をONにするのですが、この時送信元のIPをどちらも同じにしていて、片方のネットワークに所属する端末が電源が付けられたり付けられなかったりするという事象が発生しました。

当たり前と言えば当たり前なのですが、送出するLAN口を間違えれば対象のPCがいないのでWOL出来ません。

なので、出ていく口を間違えないように同じネットワークの方のアドレスを指定しようということのようです。

不明な(混乱した)点

  • 繋がる時もある。
    これが本当に厄介で、別に指定してなくてもつながるときはつながってしまいました。
    それも、「繋がる時間帯は全台繋がる」とかではなく、「一斉起動して起動する端末と起動しない端末がある」という感じで、「特定の設定をすると送信元IPに関係なく見に行ってくれる」という類のものではなさそうで、原因特定に時間がかかりました。
    (そして、この繋がるときは繋がる理由は不明のままです。)

参考

記事の作成者のA.W.のアイコン

この記事を書いた人

A.W.
茨城県在住Webエンジニアです。 PHP、PostgreSQL、Linuxなどを業務で使用しています。 趣味ではGoやNuxt、Flutterをやってます。

Comment