关于socket编程中的INADDR_ANY
2014-01-23 14:41
453 查看
在Server端bind本机IP地址和端口的时候,有些程序会使用INADDR_ANY这个地址来取代本机地址。这是为什么呢?
加了printf把INADDR_ANY打印出来看了一下,居然是零。
查了一些资料和代码,MAC中INADDR_ANY是定义在in.h中的:
所以打印出来是零。
那么,这个宏定义到底是什么含义呢?
这个宏能够让程序员在不知道本机IP地址的情况下,使用它来代表本机所有接口的IP地址。也就是说,使用这个宏作为监听地址的话,不管本机有多少个接口,socket都会监听。
举个例子,假设一个主机有inter1,inter2,,inter3三个接口,如果一个socket绑定了INADDR_ANY的地址和8000的端口,那么,从客户端过来的一个UDP包到达该主机,不管客户端connect的是inter1,inter2,inter3中的哪个地址,都会被该socket接收到。如果此时主机还要再建立一个新的socket,使用inter1接口和端口8000,将会失败,因为这个端口和地址已经被第一个socket监听了。
上面是接收的情况,那么,发送数据报给客户端的时候呢,到底是用哪个接口发送呢?
这个就是根据本机路由表的配置情况,选择最合适的路径对应的接口来发送。
下面是一个典型的服务器端程序和客户端echo回显程序:
Server:
Client:
加了printf把INADDR_ANY打印出来看了一下,居然是零。
查了一些资料和代码,MAC中INADDR_ANY是定义在in.h中的:
#define INADDR_ANY(u_int32_t)0x00000000
所以打印出来是零。
那么,这个宏定义到底是什么含义呢?
这个宏能够让程序员在不知道本机IP地址的情况下,使用它来代表本机所有接口的IP地址。也就是说,使用这个宏作为监听地址的话,不管本机有多少个接口,socket都会监听。
举个例子,假设一个主机有inter1,inter2,,inter3三个接口,如果一个socket绑定了INADDR_ANY的地址和8000的端口,那么,从客户端过来的一个UDP包到达该主机,不管客户端connect的是inter1,inter2,inter3中的哪个地址,都会被该socket接收到。如果此时主机还要再建立一个新的socket,使用inter1接口和端口8000,将会失败,因为这个端口和地址已经被第一个socket监听了。
上面是接收的情况,那么,发送数据报给客户端的时候呢,到底是用哪个接口发送呢?
这个就是根据本机路由表的配置情况,选择最合适的路径对应的接口来发送。
下面是一个典型的服务器端程序和客户端echo回显程序:
Server:
/* A simple server in the internet domain using TCP The port number is passed as an argument */ #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> void error(char *msg) { perror(msg); exit(1); } int main(int argc, char *argv[]) { int sockfd, newsockfd, portno, clilen; char buffer[256]; struct sockaddr_in serv_addr, cli_addr; int n; if (argc < 2) { fprintf(stderr,"ERROR, no port provided\n"); exit(1); } sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) error("ERROR opening socket"); bzero((char *) &serv_addr, sizeof(serv_addr)); portno = atoi(argv[1]); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_port = htons(portno); if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) error("ERROR on binding"); listen(sockfd,5); clilen = sizeof(cli_addr); newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen); if (newsockfd < 0) error("ERROR on accept"); bzero(buffer,256); n = read(newsockfd,buffer,255); if (n < 0) error("ERROR reading from socket"); printf("Here is the message: %s\n",buffer); n = write(newsockfd,"I got your message",18); if (n < 0) error("ERROR writing to socket"); return 0; }
Client:
#include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> void error(char *msg) { perror(msg); exit(0); } int main(int argc, char *argv[]) { int sockfd, portno, n; struct sockaddr_in serv_addr; struct hostent *server; char buffer[256]; if (argc < 3) { fprintf(stderr,"usage %s hostname port\n", argv[0]); exit(0); } portno = atoi(argv[2]); sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) error("ERROR opening socket"); server = gethostbyname(argv[1]); if (server == NULL) { fprintf(stderr,"ERROR, no such host\n"); exit(0); } bzero((char *) &serv_addr, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length); serv_addr.sin_port = htons(portno); if (connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0) error("ERROR connecting"); printf("Please enter the message: "); bzero(buffer,256); fgets(buffer,255,stdin); n = write(sockfd,buffer,strlen(buffer)); if (n < 0) error("ERROR writing to socket"); bzero(buffer,256); n = read(sockfd,buffer,255); if (n < 0) error("ERROR reading from socket"); printf("%s\n",buffer); return 0; }
相关文章推荐
- 关于socket编程中的INADDR_ANY
- SOCKET编程之 INADDR_ANY
- 关于socket绑定INADDR_ANY
- SOCKET编程之INADDR_ANY
- socket 关于INADDR_ANY的问题
- Linux中SOCKET编程中INADDR_ANY的含义
- 关于socket绑定INADDR_ANY
- SOCKET编程之INADDR_ANY
- 【VS开发】网络SOCKET编程INADDR_ANY选项
- socket INADDR_ANY 监听0.0.0.0地址 socket只绑定端口让路由表决定传到哪个ip
- 关于INADDR_ANY
- socket INADDR_ANY 监听0.0.0.0地址 socket只绑定端口让路由表决定传到哪个ip
- socket编程总结(三) struct sockaddr_in /struct sockaddr_in6/struct addrinfo 结构体
- 关于INADDR_ANY
- socket INADDR_ANY导致端口可以重复打开
- struct sockaddr_in等Socket编程相关数据类型定义
- socket绑定INADDR_ANY,那会怎样?(例如:双通机房多网卡多IP设置)
- socket绑定的ip为INADDR_ANY 的意义
- SOCKET bind INADDR_LOOPBACK和INADDR_ANY的区别
- socket绑定INADDR_ANY,那会怎样?(例如:双通机房多网卡多IP设置)