Adventurer3のIPアドレスの検索方法を変更。
以前までは、プライベートMACアドレスを用いたものだった。
MACアドレス固定化をしてから、上のやり方で対応できなくなってしまったので改良はしたかった。
Ver4の途中からなのか機器の検索という機能が付いていて、それに関してプロトコル解析をしたところ取り入れることができそうだったので対応した。
機器の検索について
FlashPrintでいうところの、ツールから機器へ接続する際に表示されるウィンドウ。
- Ver4.6
- Ver5.1
上のような画面が出て検索できるようになっている。
この時、ネットワークプロトコル解析をして見ると以下の様な情報が流れていた。
まずはPCからの送信情報
UDPでポート18001から225.0.0.9のポート19000に対してブロードキャスト送信をしているようだった。
上の送信の後に、機器側から以下の様な返信が来ている。
返信された情報を見る限り、機器名と機器の種類(これは想像だけど)らしき情報が送られてきていた。
つまり、上のものを対応することで機器の検索ができるようになるのか。
プログラム
Github上のものに関しては修正済み。
IPアドレスの検索は、Adventurer3.csのSearchIP()で行っていて、この部分を変更するだけになる。
実際の変更コードは以下の様になっている。
/// <summary>
/// Adventurer3のIPをサーチするクラス
/// UDPのブロードキャストで検索する
/// </summary>
public static List<IPAddress> SearchIP() {
var ips = new List<IPAddress>();
byte[] sendBytes = { 0xc0, 0xa8, 0x0b, 0x03, 0x46, 0x51, 0x00, 0x00 };
// IP一覧取り出し
// ネットワークアダプタ一覧からIPv4のホストアドレスを検索
// 見つかったIPアドレスの18001ポートから225.0.0.9の19000ポートにブロードキャストを行いその返却値から機器のIPを求める。
var interfaces = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces();
foreach (var adapter in interfaces) {
if (adapter.OperationalStatus == System.Net.NetworkInformation.OperationalStatus.Up) {
var properties = adapter.GetIPProperties();
foreach (var unicast in properties.UnicastAddresses) {
switch (unicast.Address.AddressFamily) {
case AddressFamily.InterNetwork:
if (unicast.IsDnsEligible) {
var ip = unicast.Address;
var localPort = new IPEndPoint(ip, 18001);
var udp = new UdpClient(localPort);
var targetPort = new IPEndPoint(IPAddress.Parse("225.0.0.9"), 19000);
udp.EnableBroadcast = true;
udp.Send(sendBytes, sendBytes.Length, targetPort);
udp.Client.ReceiveTimeout = 1000; // ms:タイムアウトの設定
for (; ; ) {
try {
IPEndPoint e = new IPEndPoint(IPAddress.Any, 19000);
var receiveBytes = udp.Receive(ref e);
ips.Add(e.Address);
}
catch (SocketException) {
// タイムアウト
break;
}
}
//UdpClientを閉じる
udp.Close();
}
break;
}
}
}
}
return ips;
}
まずPCに接続しているIPv4のIPが割り当てられているアドレスを調べる。
これがGetAllNetworkInterfaces()から下の部分。
これが必要なのは、複数ネットワークアダプタがあるときちんとIP指定しないとアダプタ単位に3Dプリンタの機器検索ができないため。
次にUDPのセッションを確立し、指定IP、ポートにデータを送信。
送信データに関してはプロトコルアナライザで解析した数値をそのまま使用している。
最後にUDPで機器からの返信を受信している。
受信は1000msのタイムアウトを設定して、それ以上待たないようにしている。
これで、APIのリターン値的には同じなIP一覧が取得できるようになった。
コメント