2

Linux では、getaddrinfo()ローカル ソケットでへの呼び出しを使用して、次のgetaddrinfo(NULL,port,&hints,&servinfo)ようなリストを作成できます。

   IPv4: 0.0.0.0
 | socktype: 1 |protocol: 6    IPv4: 0.0.0.0
 | socktype: 2 |protocol: 17    IPv4: 0.0.0.0
 | socktype: 3 |protocol: 0    IPv6: ::
 | socktype: 1 |protocol: 6    IPv6: ::
 | socktype: 2 |protocol: 17    IPv6: ::
 | socktype: 3 |protocol: 0

一方、Windows では、ローカル マシン"NULL", "localhost", "127.0.0.1"(実際には URL 以外のもの) に関連する呼び出しは失敗するようです。

getaddrinfo()Linux と Windowsの使用方法の意図的な違いは何ですか?

また、この種の質問が 2 つの問題になることはわかっていますが、最初のプログラムからの出力は正確には何を示しているのでしょうか。カーネルがそのポートに対して尊重できる唯一の組み合わせですか?

はい、この質問はかなり有名な「Beej のネットワーク プログラミング ガイド」から発展したものです。

これに至るまでのコードは次のとおりです。

      struct addrinfo hints,*ai,*p;

    memset(&hints,0,sizeof(hints));
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_DGRAM;
    hints.ai_flags = AI_PASSIVE;
    int error;

   memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC; // use AF_INET6 to force IPv6
hints.ai_socktype = SOCK_STREAM;

if ((error = getaddrinfo("www.example.com", "http", &hints, &ai)) != 0) {
    fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(error));
    exit(1);
} else cout <<"Success with a URL\n";


if (error=(getaddrinfo("208.117.45.202",&port,&hints,&ai))){
       cout<<"Cannot resolve any usable ports! : "<<gai_strerror(error)<< " : "<<error;
       if (ai == NULL) return -5;
}

ありがとう!

4

2 に答える 2

2

man ページと呼ばれる魔法のようなものがあります。たとえばman 3 getaddrinfo

bind()Hints.ai_flags で AI_PASSIVE フラグが指定され、node が NULL の場合、返されるソケット アドレスは、接続するソケットの ingに適して いますaccept()。返されるソケット アドレスには、「ワイルドカード アドレス」が含まれます (IPv4 アドレスの場合は INADDR_ANY、IPv6 アドレスの場合は IN6ADDR_ANY_INIT)。ワイルドカード アドレスは、任意のホストのネットワーク アドレスで接続を受け入れるアプリケーション (通常はサーバー) によって使用されます。node が NULL でない場合、AI_PASSIVE フラグは無視されます。

この関数の目的getaddrinfo()は単純です。ユーザーが指定した文字列を、アプリケーションが受信接続をリッスンするソケットまたは接続するソケットの作成に使用できる数値データに変換するのに最善を尽くします。

getaddrinfo()POSIX.1-2001 (およびRFC 2553 ) で指定されており、Microsoft は、拡張または変質する可能性のある標準に従わないことで知られているため、もちろん Windows ではまったく異なる機能です。関連するMSDN ページには、「ANSI ホスト名からアドレスへのプロトコルに依存しない変換を提供する」と記載されています。

プログラムの出力は、node(最初​​のパラメーター)がNULLでありAI_PASSIVE、フラグにあるため、指定した への着信接続をリッスンするために、プログラムがバインド(試行)できるワイルドカードアドレスのリストですport

于 2013-07-03T02:41:49.830 に答える
0

コーディングの一貫性はどうなりましたか?

memset(&hints,0,sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_PASSIVE;
int error;

memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC; // use AF_INET6 to force IPv6
hints.ai_socktype = SOCK_STREAM;

最初に;でゼロhintsにします。sizeof(hints)次に、いくつかの値を設定します。sizeof hints次に、 (不一致)で再度ゼロにします。AI_PASSIVE次に、いくつかの値をもう一度設定し、他の値 (特にフラグ)を見逃します。一貫性があれば、プログラミングは一般的に最も簡単です。また、行ったのと同じことを (多かれ少なかれ) 2 回行うことを避けることも賢明です。どちらか一方のシーケンスを選択しますが、両方を含めないでください。

これが実際に問題の原因であるかどうかは、別の問題です。Microsoft 固有の詳細については検証していませんが、Nominal Animalによる回答は多くの関連分野をカバーしています。

于 2013-07-03T06:33:45.093 に答える