2012-01-10 25 views
6

このアドレスを割り当てると、cannot assign requested addressと表示されます。しかし、ローカルアドレス(127.0.0.1)を入力すると、それを受け入れます。なぜ???実行時にLinux(Centos)のCで「要求されたアドレスを割り当てることができません」というエラーが発生しました

char* hostname = "192.168.1.8"; 

int sockfd; 
struct sockaddr_in my_addr; // my address information 
struct sockaddr_in their_addr; // connector's address information 
socklen_t addr_len; 
int numbytes; 
char buf[MAXBUFLEN]; 
int port =5000; 

if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { 
    perror("socket"); 
    exit(1); 
} 
try 
{ 
    my_addr.sin_family = AF_INET;  // host byte order 
    my_addr.sin_addr.s_addr = inet_addr(hostname); 

    printf("Accepted/n"); 
    // automatically fill with my IP 
    my_addr.sin_port = htons(5000); // short, network byte order 
    memset(&(my_addr.sin_zero), '\0', 8); // zero the rest of the struct 

    if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) 
    { 
     perror("bind"); 
     exit(1); 
    } 
    while (1) 
    { 
     addr_len = sizeof(struct sockaddr); 
     if ((numbytes = recvfrom(sockfd, buf, MAXBUFLEN-1 , 0, 
      (struct sockaddr *)&their_addr, &addr_len)) == -1) { 
      perror("recvfrom"); 
      exit(1); 
     } 

     //printf("got packet from %s\n",inet_ntoa(their_addr.sin_addr)); 
     //printf("packet is %d bytes long\n",numbytes); 
     buf[numbytes] = '\0'; 
     //printf("packet contains \"%s\"\n",buf); 
    } 

    close(sockfd); 
} 
catch(...) 
{ 
+3

あなたのマシンのローカルアドレスが192.168.1.8ではないためでしょうか? –

+2

また、これをCとタグ付けしましたが、 'try {...} catch(...){...}'ブロックが表示されます。これはC++ですか? –

答えて

11

エラーは(あなたが状態のエラーメッセージがコードに表示されませんので、それはあなたの質問の内容に基づいて、その明白ではありません)bind上で起こっている場合、それは可能性が高いですアドレスが利用できないためです。

これは通常、すでに使用されているか、現在のホストで使用できないためです。

通常、ローカルインターフェイスに割り当てられたIPアドレスにのみバインドできます。あなたは192.168.1.8がそのクラスに含まれていることを確認する必要があります。それは127.0.0.1がローカルインターフェイスになるということです(そのため、なぜ動作するのでしょうか)。INADDR_ANYも同様に動作します。つまり、自分自身を1つのインターフェイスに制限する必要がある場合を除き、おそらく "アドレス"です。

エラーが発生した機能に続いてerrnoを確認し、possibilitiesと照合してください。余談として


、これはおそらくあなたの問題とは無関係である、あなたはsockaddr_in構造(残りの部分をクリアし、その後フィールドを設定)を初期化する方法は私にはポータブル未満であるように思われます。

私は単にのようなもの、あなたはその後望むものを設定後、多くのことをクリアする方が安全だろうと思う:

memset (&my_addr, 0, sizeof (my_addr)); 
my_addr.sin_family  = AF_INET; 
my_addr.sin_addr.s_addr = inet_addr (hostname); 
my_addr.sin_port  = htons (5000); 

少なくともそのように、構造内のフィールドの順序があなたに影響を与えません。コード。


次のコードで問題が確認できます。まず、必要なヘッダー:

#define __USE_GNU 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 

次に引数のチェックとソケットの作成を行います。その後

int main (int argc, char *argv[]) { 
    int sockfd; 
    struct sockaddr_in me; 

    if (argc < 2) { 
     printf ("Need argument with IP address\n"); 
     return 1; 
    } 

    if ((sockfd = socket (AF_INET, SOCK_DGRAM, 0)) == -1) { 
     perror("socket"); 
     return 1; 
    } 

自体を結合:

memset (&me, 0, sizeof (me)); 
    me.sin_family = AF_INET; 
    me.sin_addr.s_addr = inet_addr (argv[1]); 
    me.sin_port = htons (5000); 

    if (bind (sockfd, (struct sockaddr *)&me, sizeof(struct sockaddr)) == -1) 
    { 
     fprintf (stderr, "errno = %d ", errno); 
     perror("bind"); 
     exit(1); 
    } 

    close(sockfd); 

    return 0; 
} 

あなたが特定の引数を使って、あなたはそれがIPアドレスはローカルインタフェース(127.0.0.1192.168.0.101)に属しているもののためにいい作品見ることができることを実行しますが、ない192.168.0.102のような、そうでないもののために:上記bind manページへのリンクから、

pax> ifconfig | grep 'inet addr' 
     inet addr:192.168.0.101 Bcast:192.168.0.255 Mask:255.255.255.0 
     inet addr:127.0.0.1       Mask:255.0.0.0 
     inet addr:192.168.99.1 Bcast:192.168.99.255 Mask:255.255.255.0 
     inet addr:192.168.72.1 Bcast:192.168.72.255 Mask:255.255.255.0 

pax> ./testprog 127.0.0.1 

pax> ./testprog 192.168.0.101 

pax> ./testprog 192.168.0.102 
errno = 99 bind: Cannot assign requested address 

pax> grep '#define.*99' /usr/include/asm-generic/errno.h 
#define  EADDRNOTAVAIL  99  /* Cannot assign requested address */ 

をそして、我々参照:EADDRNOTAVAIL
             

存在しないインタフェースが要求されたか、要求されたアドレスがローカルではありませんでした。

+0

これは非常に詳細なコードレビューです – bn00d

関連する問題