なんかいろいろしてみます

Dec 5, 2018 - 2 minute read - HoloLens

DirectedBroadcastAddressを取得してみる

HoloLensやPCでUDPネットワーク通信をするときにブロードキャストで全体に送りたかったのでブロードキャストアドレスを取得しました.

ブロードキャストアドレス

ブロードキャストアドレスとは特定の用途で利用されるためにあらかじめ予約されている特殊なアドレスのことです. ブロードキャストアドレスはネットワーク上のPCに同時に送信を行うことができます.

ブロードキャストアドレスにはリミテッドブロードキャスとディレクティッドブロードキャストがあります. リミテッドブロードキャストは255.255.255.255のアドレスのことです.

一方でディレクティッドブロードキャストアドレス(DirectedBroadcastAddress)はネットワークのIPアドレスとサブネットマスクを組み合わせて作成するアドレスです. 例えばIPアドレスが192.168.1.0,サブネットマスクが255.255.255.0の場合,ディレクティッドブロードキャストアドレスは192.168.1.255となります.

一般的なルーターではセキュリティ強化のためリミテッドブロードキャストによる通信ができない場合が多いみたいです. そのためディレクティッドブロードキャストアドレスを使うようにします.

IPアドレス,サブネットマスク,ブロードキャストに関する詳しい情報の説明は割愛します.

DirectedBroadcastAddressを取得する

  • C#で取得できるブロードキャストアドレスはリミテッドブロードキャストなので自分のIPアドレスとサブネットマスクからディレクティッドブロードキャストアドレスを取得します.
  • リミテッドブロードキャストアドレス IPAddress.Broadcast
  • 通常のC#とHoloLensのUWPでは利用できる関数が異なるので別々に取得機能を実装します.
  • Unityでは自分のIPアドレスはUnityEngine.Network.player.ipAddressで取得できます.

PC(C#)編

  • 自分のIPアドレスの取得
123456789
  string hostname = Dns.GetHostName();
  var address = Dns.GetHostAddresses(hostname);
  foreach (var item in address)
  {
      if (item.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork && !item.ToString().StartsWith("172."))
      {
          ipaddress = item.ToString();// アドレス
      }
  }
  • サブネットマスクの取得
 1 2 3 4 5 6 7 8 91011121314151617181920
 var info = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces();
  foreach (var item in info)
  {
      if (item.OperationalStatus == System.Net.NetworkInformation.OperationalStatus.Up &&
          item.NetworkInterfaceType != System.Net.NetworkInformation.NetworkInterfaceType.Loopback &&
          item.NetworkInterfaceType != System.Net.NetworkInformation.NetworkInterfaceType.Tunnel)
      {
          var ips = item.GetIPProperties();
          if (ips != null)
          {
              foreach (var ip in ips.UnicastAddresses)
              {
                  if (IPAddress == ip.Address.ToString())
                  {
                      subnetmask = ip.IPv4Mask.ToString();// サブネットマスク
                  }
              }
          }
      }
  }

HoloLens(UWP)編

  • 自分のIPアドレスの取得
 1 2 3 4 5 6 7 8 91011
 var host = NetworkInformation.GetHostNames();
  foreach (var item in host)
  {
      if (item.Type == Windows.Networking.HostNameType.Ipv4 && item.IPInformation != null)
      {
          if (item.DisplayName.IndexOf("172.") == -1)
          {
              ipaddress = item.DisplayName;// アドレス
          }
      }
  }
  • サブネットマスクの取得
 1 2 3 4 5 6 7 8 910111213141516171819
 var host = NetworkInformation.GetHostNames();
  foreach (var item in host)
  {
      if (item.Type == Windows.Networking.HostNameType.Ipv4 && item.IPInformation != null)
      {
          if (item.DisplayName.IndexOf("172.") == -1)
          {
              byte length = item.IPInformation.PrefixLength.Value;
              BitArray bit = new BitArray(32, false);
              for (int i = 0; i < length; i++)
              {
                  bit[i] = true;
              }
              byte[] c1 = new byte[4];
              ((ICollection)bit).CopyTo(c1, 0);
              subnetmask = c1[0].ToString() + "." + c1[1].ToString() + "." + c1[2].ToString() + "." + c1[3].ToString(); // サブネットマスク
          }
      }
  }

DirectedBroadcastAddress取得

  • 上記で取得したIPアドレスとサブネットマスクを利用してDirectedBroadcastAddressを取得します.
  • bit演算でIPアドレスからネットワークアドレス部分とホストアドレス部分に分割し,ホストアドレス部分のbitを全て1にしています.
 1 2 3 4 5 6 7 8 9101112
byte[] ipb = new byte[4];
  var ips = IPAddress.Split('.');
  string address = "";
  if (ips != null && ips.Length == 4)
  {
      var masks = Subnetmask.Split('.');
      for (int i = 0; i < 4; i++)
      {
          ipb[i] = (byte)(byte.Parse(ips[i]) | ~byte.Parse(masks[i]));
      }
      address = ipb[0].ToString() + "." + ipb[1].ToString() + "." + ipb[2].ToString() + "." + ipb[3].ToString(); // ブロードキャストアドレス
  }

まとめ

  • 同一ネットワークにいれば通信できるので入力の手間が省ける
  • ルーターの設定によっては通信できない場合もある
  • 次はDirectedBroadcastAddressを使ってブロードキャストアドレスで通信までしてみる予定