在Linux下(Centos),我在运行时遇到了错误:“Can not assign requested address”

当我分配这个地址,它说cannot assign requested address 。 但是当我把本地地址(127.0.0.1)它接受它。 为什么???

 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(...) { 

如果错误发生在bind (根据您的问题内容,​​这不是显而易见的,因为您声明的错误消息没有出现在代码中),这很可能是因为地址不可用。

这通常是因为它已经在使用,或者在当前主机上不可用。

除了少数例外情况,您通常只能绑定到分配给本地接口的IP地址。 你应该检查192.168.1.8是否属于这个类。 127.0.0.1是一个本地接口(因此它是为什么起作用),而且INADDR_ANY也可以工作 – 这可能是你应该使用的“地址”,除非你真的需要将自己限制在一个接口上。

你应该检查errno功能之后的errno ,并将其与可能性进行匹配。


顺便说一句,这可能与您的问题无关,您初始化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.101的那些接口没有问题:

 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 */ 

而从上面的bind手册页的链接中,我们看到:

EADDRNOTAVAIL
一个不存在的接口被请求或请求的地址不是本地的。