DOBON.NETプログラミング道掲示板
(現在 過去ログ4 を表示中)
HOME
HELP
新規作成
新着記事
トピック表示
発言ランク
ファイル一覧
検索
過去ログ
[
最新記事及び返信フォームをトピックトップへ
]
[ トピック内全6記事(1-6 表示) ] <<
0
>>
■34656
/ inTopicNo.1)
.NetでのIPv6の比較
▼
■
□投稿者/ あばば無人君
一般人(30回)-(2021/02/26(Fri) 14:39:28)
環境/言語:[Windows10(2004) 64bit、.Net 5.0、VS2019(16.8.5)Com版、C#]
分類:[.NET]
いつも本掲示板でお勉強させていただいております。
さてタイトルの件ですが、ご存知の通りIPv6は同じアドレスでも
以下の様に複数の表記が可能です。
2001:db8:0:0:1:0:0:1
2001:0db8:0:0:1:0:0:1
2001:db8::1:0:0:1
2001:db8::0:1:0:0:1
2001:0db8::1:0:0:1
2001:db8:0:0:1::1
2001:db8:0000:0:1::1
2001:DB8:0:0:1::1
そこで質問なのですが.Netのライブラリで表記(文字列)の異なる
IPv6アドレスが等しいかチェックできる様なクラスなどあったり
しませんでしょうか?
普通にありそうな機能かと思ってネットを検索したのですが、
私の見た限りでは発見できませんでした。
理想としては
XXXClass addPattern1 = new XXXClass("2001:db8:0:0:1:0:0:1");
XXXClass addPattern2 = new XXXClass("2001:DB8:0:0:1::1");
if (addPattern1.Equals(addPattern2)) { Debug.WriteLine("等しい"); }
的な感じです。
自分でも作れはしますが、もし.Netにあったら勿体ないので
どなたかご存知の方がいらっしゃいましたら教えて下さい。
以上です。宜しくお願い致します。
引用返信
削除キー/
編集
削除
■34657
/ inTopicNo.2)
Re[1]: .NetでのIPv6の比較
▲
▼
■
□投稿者/ Hongliang
大御所(597回)-(2021/02/26(Fri) 14:51:53)
System.Net名前空間のIPAddressクラスを使えばいいのではないでしょうか。
文字列からはIPAddress.Parse静的メソッド(またはTryParse静的メソッド)でインスタンス化できます。
引用返信
削除キー/
編集
削除
■34658
/ inTopicNo.3)
Re[2]: .NetでのIPv6の比較
▲
▼
■
□投稿者/ あばば無人君
一般人(32回)-(2021/02/26(Fri) 15:30:29)
Hongliangさん、ご返信ありがとうございます。
IPAddressクラスでのIPv6アドレス比較、できちゃいました…。
以前このクラスで以下の様にIPv4アドレスで
文字列比較とインスタンス比較した時に
IPAddress add1 = IPAddress.Parse("172.17.22.100");
IPAddress add2 = IPAddress.Parse("172.017.022.100");
if (add1.Equals(add2)) { Debug.WriteLine($"等しい"); }
if (add1.ToString().Equals(add2.ToString())) { Debug.WriteLine($"等しい"); }
「等しくない」判定されたのでIPv6でも同じかと思っていました。
まさかIPv6だと「等しい」判定になるとは…。
何故IPv4だと等しくないのかは分かりませんが、
ひとまずタイトルの件は解決したので解決済みと
させていただきます。
迅速な回答、ありがとうございました。
解決
済
み!
引用返信
削除キー/
編集
削除
■34659
/ inTopicNo.4)
Re[3]: .NetでのIPv6の比較
▲
▼
■
□投稿者/ Hongliang
大御所(598回)-(2021/02/26(Fri) 15:40:50)
2021/02/26(Fri) 15:52:43 編集(投稿者)
IPv4において、0プリフィクスがついている桁は8進数を意味します。
Trace.WriteLine(IPAddress.Parse("172.017.022.100"));
=> 172.15.18.100
// ただし0プリフィクスがあっても普通に10進数で扱う流儀もあるのでいかんともしがたいですが。
ちなみに0xプリフィクスで16進数表記もできます。
解決
済
み!
引用返信
削除キー/
編集
削除
■34660
/ inTopicNo.5)
Re[4]: .NetでのIPv6の比較
▲
▼
■
□投稿者/ あばば無人君
一般人(33回)-(2021/02/26(Fri) 17:18:20)
Hongliangさん、再度返信ありがとうございます。
> IPv4において、0プリフィクスがついている桁は8進数を意味します。
> Trace.WriteLine(IPAddress.Parse("172.017.022.100"));
> => 172.15.18.100
おぉ!
int i = 0x01;
の様な数値リテラルだけでなく、上記の様な文字列
(しかも.で区切られた途中のオクテットに対して)でも
プレフィックスが有効になるのですね。
等しくない扱いになるのは当然だったと(^_^;)
細かい部分のフォローまでありがとうございました。
解決
済
み!
引用返信
削除キー/
編集
削除
■34661
/ inTopicNo.6)
Re[5]: .NetでのIPv6の比較
▲
▼
■
□投稿者/ あばば無人君
一般人(34回)-(2021/02/26(Fri) 18:17:53)
本件、微妙なオチまでつきました。
Hongliangさんに教えて頂いたIPAddressクラスによる比較と、
その他ネットを見ていたらNetworkInterfaceクラスから
アダプタに設定されているIPアドレスをIPAddressクラスで
取得できることを知り、以下の様なパソコンのNICに引数の
IPアドレスが存在するかチェックする関数を作成しました。
public bool ExistIpAddress(string ipAddress)
{
// 戻り値(初期値:存在しない)
bool result = false;
try
{
// 引数IPアドレス文字列からIPAddressクラスを生成
IPAddress ipObj = IPAddress.Parse(ipAddress);
// IPアドレスリストを生成
List<IPAddress> addList = new List<IPAddress>();
StringBuilder logStr = new StringBuilder();
logStr.AppendLine($"有効なネットワークインターフェースカードとそのIPアドレス");
// 全てのネットワークインターフェース(アダプタ)の数だけ繰り返す
foreach (NetworkInterface adapter in NetworkInterface.GetAllNetworkInterfaces())
{
// 有効(=稼働中)なアダプタでなければ次へ
if (adapter.OperationalStatus != OperationalStatus.Up) { continue; }
logStr.AppendLine($"{adapter.Name}({adapter.OperationalStatus})");
// アダプタに設定された全IPアドレス情報を取得
// ※1つのアダプタに複数のIPアドレスを設定できる点に注意!
IPInterfaceProperties ifProperties = adapter.GetIPProperties();
// 全IPアドレス情報をリストに追加
foreach (UnicastIPAddressInformation info in ifProperties.UnicastAddresses)
{
// IPアドレス情報がIPv4かIPv6の場合
if (info.Address.AddressFamily == AddressFamily.InterNetwork
|| info.Address.AddressFamily == AddressFamily.InterNetworkV6)
{
// そのままIPアドレスリストに追加
addList.Add(info.Address);
logStr.AppendLine($" {info.Address}");
}
}
}
// 引数IPアドレスが存在するかチェック
result = addList.Any(a => a.Equals(ipObj));
// 存在しなかった場合だけログを出す
if (!result)
{
logStr.AppendLine($"IPアドレス[{ipAddress}]は存在しません");
Debug.WriteLine(logStr.ToString());
}
}
catch (Exception ex)
{
Debug.WriteLine(ex.ToString());
}
return result;
}
試しにこの関数の引数にローカルPCのIPv6アドレス文字列を
渡して動作確認してみたところ、「存在しない」となりました。
原因を調べたところ、NetworkInterfaceクラスから取得できる
IPAddressクラスにはIPアドレスの末尾に「スコープID」という
NICを識別するコードが付いており、その情報まで込みで
比較を行うために「存在しない」判定となっておりました。
よってIPv6アドレスの場合は以下の様に再度IPAddressクラスを
生成し直して比較することになりました。※修正箇所のみ記載
// IPアドレス情報がIPv4の場合
if (info.Address.AddressFamily == AddressFamily.InterNetwork)
{
// そのままIPアドレスリストに追加
addList.Add(info.Address);
logStr.AppendLine($" {info.Address}");
}
// IPアドレス情報がIPv6の場合
else if (info.Address.AddressFamily == AddressFamily.InterNetworkV6)
{
// NetworkInterfaceクラスから取得できるIPv6アドレスの場合は末尾にスコープIDが付加されており
// スコープIDが付加された状態のIPAddressクラスだと↓のEquals関数による存在チェックで
// 等しいと判定されないので、スコープIDを除去したIPアドレスで再度IPAddressクラスを生成した!
// ※スコープIDは「%」より後ろに記述されている
string[] addScope = info.Address.ToString().Split("%".ToCharArray());
addList.Add(IPAddress.Parse(addScope[0]));
logStr.AppendLine($" {addScope[0]}");
}
結局泥臭いコードが入ってしまいました。
ちゃんちゃん。
では、長くなりましたがこの辺で。
解決
済
み!
引用返信
削除キー/
編集
削除
トピック内ページ移動 / <<
0
>>
このトピックに書きこむ
過去ログには書き込み不可
Mode/
通常管理
表示許可
Pass/
HOME
HELP
新規作成
新着記事
トピック表示
発言ランク
ファイル一覧
検索
過去ログ
-
Child Tree
-