原文:///http://www.tuicool.com/articles/FjEJBr
在Server端bind本机IP地址和端口的时候,有些程序会使用INADDR_ANY这个地址来取代本机地址。这是为什么呢?
加了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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | /* 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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | #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; } |