环回接口上的客户端服务器连接

问题描述:

我正在尝试使用本地主机地址来测试客户端服务器的简单实现。 这是代码。环回接口上的客户端服务器连接

服务器:

/* 
* 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?

它看起来像你逝去的第三个参数来接受()未初始化的,它应该在第二个参数的大小来设定。除此之外,它应该是一个socklen_t的,而不是一个int,看到http://pubs.opengroup.org/onlinepubs/009695399/functions/accept.html

可以通过声明client_addr_l为socklen_t的尝试,然后传递给接受之前将其设置为sizeof(结构SOCKADDR_IN)()?

我猜它的单位化值是零,所以accept()不能设置远程地址给你的client_addr,因为它的大小为零。所以,client_addr是没有变化的,并且在你早些时候调零的时候,你会得到0.0.0.0。

+0

刚试过把它声明为socklen_t并正确地将它设置为struct的大小,然后我得到期望值:“与127.0.0.1连接”。 – 2013-03-14 14:30:57

+0

谢谢!我完全忘记初始化它!我也获得了预期的价值! – 2013-03-14 15:21:30

0.0.0.0意味着你的服务器接受您的设备

所以与地址127.0..0.1 loopback接口包括

+0

它会显示真正的TCP/IP(外部)连接的实际地址?或者它只显示0.0.0.0。 – 2013-03-14 13:58:16

+0

你可以从你的c代码中得到接收到的数据包的源地址和目标地址。因此,如果您使用的是回送接口,则目标地址将为127.0.0.1,而不是0.0.0.0,并且源地址也将为127.0.0.1 – MOHAMED 2013-03-14 14:06:30

+0

因此,'printf(“与...连接:%s \ n”,inet_ntoa(client_addr。 sin_addr));'这不是一个有效的调用来显示实际的远程地址? – 2013-03-14 14:29:20

这似乎是一个特殊情况,从任何接口连接。所有可能的地址都在监听您的连接。 Here是一个线程。

报价:

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). 
+0

那它取决于我的机器?它会在每种情况下显示0.0.0.0,或者仅显示回送? – 2013-03-14 13:59:48

+0

@FabioCarello我不这么认为。毕竟,你有一个特殊的情况,你正在自己的本地机器上工作。 – 2013-03-14 14:03:11