2012-02-17 4 views
2

以下は、クライアントからの接続を受け入れるために書いたコードスニペットです。私はリモートホスト名を印刷したかったのです。 getnameinfo()はエラーで失敗します:ai_familyはサポートされていません。私はAF_UNSPECを指定するようにインターネット上でさまざまなオプションを試しました。何も私のために働いていません。 sa_familyフィールドが表示され、62752です。これは有効な値ですか?私は間違って何をしています。どんな助けもありがたい。ai_familyの有効な値は何ですか?

socklen_t sin_size; 
struct sockaddr client_addr; 
int sockfd = accept(serv_sockfd,&client_addr, &sin_size); 
if(sockfd == -1) 
    error("Accept failed"); 

char remote_host[NI_MAXHOST]; 
cerr <<"sa_family" << client_addr.sa_family<<endl; 

int en; 
if ((en = getnameinfo(&client_addr, sin_size, remote_host, sizeof(remote_host),NULL, 0, NI_NAMEREQD))!=0) 
cerr << "getnameinfo: " << gai_strerror(en); 
else 
    printf("host=%s\n", remote_host); 
+0

acceptを呼び出す前に、使用しているアドレス構造体のサイズに 'sin_size'変数を設定する必要があります。 –

+0

ありがとう、それは今働いています。私はこれが馬鹿に聞こえるかもしれないことを知っています、どう思いましたか?ちょうどコードを見て、またはゴミ値62752は私がいくつかの構造を台無しにしたことを示唆していますか? – FourOfAKind

+0

コードを見て、「受け入れる」が何を望んでいるかを覚えておいてください。 :) –

答えて

1

あなたのバグは早いです。 accept()の三番目の引数は、ことになっている:

address_len

Points to a socklen_t structure which on input specifies the length of the supplied sockaddr structure, and on output specifies the length of the stored address.

また、struct sockaddrは、任意の実際のアドレスを保持するには小さすぎます。

試してみてください。

struct sockaddr_storage client_addr; 
socklen_t sin_size = sizeof(client_addr); 
int sockfd = accept(serv_sockfd, (struct sockaddr *)&client_addr, &sin_size); 

...と書かれたコードの後、残りの部分。

+0

コードがIPv4だけを使用している場合は、 'sockaddr'が代わりに使用されるべきですが、' sockaddr'は十分に大きいです。コードがIPv4とIPv6、または他のアドレスファミリの両方をサポートする必要がある場合は、 'yes 'に' sockaddr_storage'を使用します。 –

+0

ありがとうございます。もう一つ質問があります。どちらがsin_family/ai_family、サーバーまたはクライアントを指定する必要がありますか?申し訳ありません。 – FourOfAKind

+0

ファミリは、 'socket()'を呼び出してどちらかの端に新しいソケットを作成するたびに確立されます。 'connect()'を呼び出すと、IPv4クライアントはIPv4またはIPv6デュアルスタックサーバとしか通信できず、IPv6クライアントはIPv6サーバなどとしか通信できません。 'accept()'はクライアントの家族'recvfrom()'は、データなどを送信したピアの家族を示します。 –

関連する問題