1

我正在尝试使用 localhost 地址测试客户端-服务器的简单实现。这是代码。

服务器:

/*
 * Sequential busy-waiting
 */
int main(int argc, char** argv) {

    int opt, client_addr_l, errsv;
    unsigned short port;
    struct sockaddr_in server_addr, client_addr;

    /* ... */

    printf("Port number retrieved (%d), server is starting ...\n", port);

    /*TCP Socket creation*/
    sock_ds = socket(AF_INET, SOCK_STREAM, 0); 
    if(sock_ds == -1){
        fprintf(stderr, "Socket creation error: %s\n", strerror(errno));
        exit(EXIT_FAILURE);
    }

    /*Server address binding*/
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(port);
    server_addr.sin_addr.s_addr = INADDR_ANY;

   /*!!!! */
   int optval = 1;                                      
   if( (setsockopt(sock_ds,SOL_SOCKET,SO_REUSEADDR,&optval,sizeof(optval))) == -1 ) {                
       printf("Error on setsockopt\n");                         
       exit(EXIT_FAILURE);                                  
   }
  /*????*/

   if(bind(sock_ds, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1){
       fprintf(stderr, "Address binding error\n");
       exit(EXIT_FAILURE);
   }

   /*Server with passive socket*/
   if(listen(sock_ds, SOMAXCONN) == -1){
       fprintf(stderr, "Listen call error: %s\n", strerror(errno));
       exit(EXIT_FAILURE);
   }

   while(1){
       memset(&client_addr, 0, sizeof(client_addr));
       acc_sock_ds = accept(sock_ds, (struct sockaddr *)&client_addr, &client_addr_l);
       printf("DEBUG: LINE201, acc_sock_ds = %d\n", acc_sock_ds);
       /*Connect error management*/
       if(acc_sock_ds == -1){
           fprintf(stderr, "Fatal error on accept %d(%s)\n"
                   , errsv, strerror(errsv));
            exit(EXIT_FAILURE);
       }

       //sin_addr to ASCII (string) );
       printf("Connected with: %s\n", inet_ntoa(client_addr.sin_addr)); 

       /*...*/     

       close(acc_sock_ds);

      /*...*/
    }

/*...*/

}

客户:

 int main(){

    int sock_ds;
    struct sockaddr_in remote_addr;
    struct hostent *hp;

    /*TCP Socket creation*/
    sock_ds = socket(AF_INET, SOCK_STREAM, 0); 
    if(sock_ds == -1){
        fprintf(stderr, "Socket creation error\n");
        exit(EXIT_FAILURE);
    }

    remote_addr.sin_family = AF_INET;
    remote_addr.sin_port = htons(25556);

    hp = gethostbyname("localhost");
    bcopy(hp -> h_addr, &remote_addr.sin_addr, hp -> h_length); //fills address entry

   if(connect(sock_ds, (struct sockaddr*)&remote_addr, sizeof(remote_addr)) == -1){ //connection attempt
       fprintf(stderr, "Connect failure(%s)\n", strerror(errno));
       exit(EXIT_FAILURE);        
   }

   /*...*/

}

当我在两个不同的终端上运行它们时,服务器返回我:

Port number retrieved (25556), server is starting ...
Server is ready. Waiting for client connections.
DEBUG: LINE201, acc_sock_ds = 4
Connected with: 0.0.0.0

我的问题是:为什么服务器检索到的客户端地址是0.0.0.0。它不应该是 127.0.0.1 吗?

4

4 回答 4

1

看起来您将第三个参数传递给未初始化的accept(),它应该设置为第二个参数的大小。除此之外,它应该是 socklen_t,而不是 int,请参阅http://pubs.opengroup.org/onlinepubs/009695399/functions/accept.html

可以尝试通过将 client_addr_l 声明为 socklen_t,然后在传递给 accept() 之前将其设置为 sizeof(struct sockaddr_in) 吗?

我猜它的未初始化值为零,因此 accept() 无法将远程地址设置为您的 client_addr,因为它的大小为零。因此,client_addr 保持不变,当您之前将其归零时,您将获得 0.0.0.0。

于 2013-03-14T14:29:39.973 回答
1

0.0.0.0表示您的服务器接受来自您设备中任何接口的连接

所以127.0..0.1包含地址的环回接口

于 2013-03-14T13:53:20.023 回答
1

这似乎是一种特殊情况。所有可能的地址都在监听您的连接。 是一个关于此的线程。

引用:

0.0.0.0, in this context, means "all IP addresses on the local machine" 
(in fact probably, "all IPv4 addresses on the local machine"). 
So, if your webserver machine has two ip addresses, 192.168.1.1 and 10.1.2.1, 
and you allow a webserver daemon like apache to listen on 0.0.0.0, 
it will be reachable at both of those IPs. 
But only to what can contact those IPs and the web port(s).
于 2013-03-14T13:55:02.087 回答
1
server_addr.sin_addr.s_addr = INADDR_ANY;

可能应该是

server_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
于 2018-07-13T12:52:22.833 回答