关于socket编程中的INADDR_ANY

原文:///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:










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:










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; 
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值