IPアドレスを記録する別の方法(バージョン2)

9月のIPアドレスを記録する別の方法の記事を読んだ後、どのようなスマートプログラムが存在するのか疑問に思って忘れていました。



最近、ローカル開発のためにmpiをインストールする必要がありました。 MS MPIとMPICHの両方を試してみましたが、MSDNが言うように、どちらも明らかなネットワークエラー10051で終了しました。これは、ネットワークが利用できないことを意味します。 私はそれを克服するために長い間試みました、私はすでにOSとソフトウェアパッケージ自体について考えていました、私はネットワークインターフェースを再作成しました。 しかし、すべてが少し異なって判明しました...



それから私は偶然IPアドレスに関するメモを思い出し、それが私に気づき、私はコンピューターに珍しい名前を付けました:0x0A0D。 恐れが確認され、この名前はすぐにIPアドレスに変換され、mpiプログラムはディスパッチャーに接続できませんでした。



OC Windows



それで、すべてのプログラムはとてもスマートですか? まず、MS Windows OS pingユーティリティが着信パラメーターをIPアドレスに解決する方法を見てみましょう。 これは、WinSockライブラリのPOSIX互換関数getaddrinfoを使用して行われます。 次のようになります。

struct addrinfo hints;

ZeroMemory( &hints, sizeof (hints) );

hints.ai_flags = AI_NUMERICHOST;



dwRetval = getaddrinfo(argv[1], NULL, &hints, &result);

if ( dwRetval != 0 ) {

hints.ai_flags = AI_CANONNAME;

dwRetval = getaddrinfo(argv[1], NULL, &hints, &result);

if ( dwRetval != 0 ) {

printf( "getaddrinfo failed with error: %d\n" , dwRetval);

WSACleanup();

return 1;

}

}




* This source code was highlighted with Source Code Highlighter .






彼女の説明は次のとおりです。

int WSAAPI getaddrinfo(

__in const char *nodename,

__in const char *servname,

__in const struct addrinfo *hints,

__out struct addrinfo **res

);



* This source code was highlighted with Source Code Highlighter .






最も興味深いパラメーターはヒントです。これは、入力文字列のノード名を解釈するためのヒントとして機能します。 ai_flagsフィールドは、着信文字列をアドレスに変換するロジックが依存するいくつかの値を取ることができます。 他の多くのプログラムと同様に、pingユーティリティでは、最初に文字列をIPアドレスに直接変換する試みが行われ、その後でDNSサブシステムを通じて繰り返されます。 これは非常に論理的かつ合理的です。



では、直接変換を強制するとどうなりますか? winsockコードの腸には、多くの変換とチェックがありますが、最終的に実行フローはNtdll.dllライブラリのRtlIpv4StringToAddressW関数に到達します 。 ところで、この関数はネットワークサブシステムから完全に独立しており、WinSockを明示的に初期化せずに使用できます。 IPアドレスを記録するためのあらゆる種類のオプションの解釈を実行するだけです。 MSDNはすべての形式について語っていますが、なぜ正確なのですか?



Linux OS



このオペレーティングシステムでは、ソースと多くのユーティリティが公開されているため、すべてがはるかにシンプルになります。 Linuxのpingユーティリティの最初のソースを見つけた後、文字列をIPアドレスに変換する方法を確認できます。

bzero(( char *)&whereto, sizeof ( struct sockaddr) );

to->sin_family = AF_INET;

to->sin_addr.s_addr = inet_addr(av[0]);

if (to->sin_addr.s_addr != (unsigned)-1) {

strcpy(hnamebuf, av[0]);

hostname = hnamebuf;

} else {

hp = gethostbyname(av[0]);

if (hp) {

to->sin_family = hp->h_addrtype;

bcopy(hp->h_addr, (caddr_t)&to->sin_addr, hp->h_length);

hostname = hp->h_name;

} else {

printf( "%s: unknown host %sn" , argv[0], av[0]);

exit(1);

}

}




* This source code was highlighted with Source Code Highlighter .






ご覧のとおり、コードは異なりますが、関数の目的が決まっているため、アルゴリズムが同一であることを理解できます。 man inet_addrを読んだ後 、この関数がWindows OSのRtlIpv4StringToAddressWに似ていることが明らかになります。 また、その説明には、神秘的な標準POSIX.1-2001が記載されています。



POSIX.1-2001標準



そのため、標準では、関数は次のいずれかの形式の文字列を受け入れる必要があります。



IPアドレスのドット表記のすべての部分は、ISO Cに準拠した10進、8進、または16進表記の数字でなければなりません。



結論



  1. アドレスに直接変換できないコンピューターのネットワーク名を選択する必要があります。そうしないと、名前でコンピューターにアクセスできない場合があります
  2. IP4アドレス変換は、IPv6アドレスの書き込みやURL形式とは関係ありませんが、IP4アドレスはIPv6アドレスのサブセットです
  3. これは、POSIX互換システムでのみ機能し、最初にアドレスを直接変換しようとするプログラムでのみ機能します(一部のLinuxでは、aのようなアドレスは受け入れられません)
  4. ローカル接続の場合、コンピューター名ではなく、localhostという名前を使用することをお勧めします。




参照資料



IPアドレスを記録する別の方法

pingページ

inet_addr IEEE Std 1003.1



All Articles