linux – 关于INADDR_ANY的问题
struct sockaddr_in server_address; int server_sockfd = socket(AF_INET,SOCK_STREAM,0); memset(&server_address,sizeof(struct sockaddr_in)); server_address.sin_family = AF_INET; server_address.sin_addr.s_addr = htonl(INADDR_ANY); // here is my quesion server_address.sin_port = htons(9734); bind(server_sockfd,(struct sockaddr*)&server_address,sizeof(server_address)); 问题> 如果我们将套接字绑定到特定的IP地址,则套接字只能接收发送到该IP地址的UPD / TCP请求. 正如我在上面的代码中所示,现在套接字server_sockfd与INADDR_ANY绑定. //更新客户端代码// int main(int argc,char *argv[]) { struct sockaddr_in6 svaddr; int sfd,j; size_t msgLen; ssize_t numBytes; char resp[BUF_SIZE]; if (argc < 3 || strcmp(argv[1],"--help") == 0) usageErr("%s host-address msg...n",argv[0]); /* Create a datagram socket; send to an address in the IPv6 somain */ sfd = socket(AF_INET6,SOCK_DGRAM,0); /* Create client socket */ if (sfd == -1) errExit("socket"); memset(&svaddr,sizeof(struct sockaddr_in6)); svaddr.sin6_family = AF_INET6; svaddr.sin6_port = htons(PORT_NUM); if (inet_pton(AF_INET6,argv[1],&svaddr.sin6_addr) <= 0) fatal("inet_pton failed for address '%s'",argv[1]); /* Send messages to server; echo responses on stdout */ for (j = 2; j < argc; j++) { msgLen = strlen(argv[j]); if (sendto(sfd,argv[j],msgLen,(struct sockaddr *) &svaddr,sizeof(struct sockaddr_in6)) != msgLen) fatal("sendto"); numBytes = recvfrom(sfd,resp,BUF_SIZE,NULL,NULL); if (numBytes == -1) errExit("recvfrom"); printf("Response %d: %.*sn",j - 1,(int) numBytes,resp); } exit(EXIT_SUCCESS); } //为服务器端代码更新 int main(int argc,char *argv[]) { struct sockaddr_in6 svaddr,claddr; int sfd,j; ssize_t numBytes; socklen_t len; char buf[BUF_SIZE]; char claddrStr[INET6_ADDRSTRLEN]; /* Create a datagram socket bound to an address in the IPv6 somain */ sfd = socket(AF_INET6,0); if (sfd == -1) errExit("socket"); memset(&svaddr,sizeof(struct sockaddr_in6)); svaddr.sin6_family = AF_INET6; svaddr.sin6_addr = in6addr_any; /* Wildcard address */ svaddr.sin6_port = htons(PORT_NUM); if (bind(sfd,sizeof(struct sockaddr_in6)) == -1) errExit("bind"); /* Receive messages,convert to uppercase,and return to client */ for (;;) { len = sizeof(struct sockaddr_in6); numBytes = recvfrom(sfd,buf,(struct sockaddr *) &claddr,&len); if (numBytes == -1) errExit("recvfrom"); /* Display address of client that sent the message */ if (inet_ntop(AF_INET6,&claddr.sin6_addr,claddrStr,INET6_ADDRSTRLEN) == NULL) printf("Couldn't convert client address to stringn"); else printf("Server received %ld bytes from (%s,%u)n",(long) numBytes,ntohs(claddr.sin6_port)); for (j = 0; j < numBytes; j++) buf[j] = toupper((unsigned char) buf[j]); if (sendto(sfd,numBytes,len) != numBytes) fatal("sendto"); } } //更新了如何运行此服务器/客户端程序. $./server_program & [1] 31047 $./client_program ::1 ciao // Send to server on local host Server received 4 bytes from (::1,32770) Response 1: CIAO 解决方法
它不会获得对互联网上每个IP地址的请求(a),它会收到它所服务的每个IP地址的请求.例如,它可能有多个NIC,每个NIC都有一个单独的IP地址,或者它可能有一个能够管理多个IP地址的NIC(它甚至可能有多个NIC,每个NIC都能够处理多个IP地址).
要看的关键片段是:
换句话说,您可能有一个多宿主设置,其中您的计算机服务10.0.0.15和10.0.0.16.使用INADDR_ANY将允许您为这两个地址获取流量,而不会获取10.0.0.17的请求,这可能是工作台另一端(或地球的另一端)的机器. 下表中,顶行是请求目的地,左列是您正在侦听的地址,显示您是否会收到请求(Y)或不(N): Request to> 10.0.0.15 10.0.0.16 10.0.0.17 Bind to: *------------------------------- 10.0.0.15 | Y N N 10.0.0.16 | N Y N INADDR_ANY | Y Y N (a)它甚至没有看到网上的绝大多数请求.绝大多数甚至没有到最近的路由器(或者甚至是你的ISP).即使那些确实能够到达最近的路由器,您的特定机器也可能看不到它们是否指定本地段上的另一台机器(尽管有混杂模式). (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |