C 环回接口上的客户机-服务器连接

C 环回接口上的客户机-服务器连接,c,localhost,connect,C,Localhost,Connect,我正在尝试使用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(

我正在尝试使用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?

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

因此,包含地址为127.0..0.1的环回接口

0.0.0意味着您的服务器接受来自设备中任何接口的连接


因此包含地址为127.0..0.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).

这似乎是一种特殊情况。所有可能的地址都在侦听您的连接。 这上面有一根线

引述:

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

看起来您正在将第三个参数传递给accept uninitialized,它应该设置为第二个参数的大小。除此之外,它应该是socklen\u t,而不是int,请参见

是否可以尝试将客户端地址声明为socklen,然后在传递到accept之前将其设置为sizeof struct sockaddr


我猜它的单位化值是零,所以accept无法将远程地址设置为您的client_addr,因为它的大小为零。因此,client_addr未被触动,当您之前将其归零时,将得到0.0.0.0。

看起来您正在传递第三个参数以接受未初始化,它应该设置为第二个参数的大小。除此之外,它应该是socklen\u t,而不是int,请参见

server_addr.sin_addr.s_addr = INADDR_ANY;
是否可以尝试将客户端地址声明为socklen,然后在传递到accept之前将其设置为sizeof struct sockaddr

我猜它的单位化值是零,所以accept无法将远程地址设置为您的client_addr,因为它的大小为零。因此,client_addr是未被触及的,正如您之前将其归零一样,您得到了0.0.0.0

server_addr.sin_addr.s_addr = INADDR_ANY;
也许应该是

server_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
也许应该是

server_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);

它将显示具有真实TCP/IP外部连接的实际地址?或者它仍然显示为0.0.0.0。您可以从c代码中收到的数据包中获取源地址和目标地址。因此,如果使用环回接口,则目标地址将是127.0.0.1而不是0.0.0.0,源地址也将是127.0.0.1,以便打印连接:%s\n,inet\u ntoaclient\u addr.sin\u addr;显示实际远程地址不是有效的调用?它将使用实际TCP/IP外部连接显示实际地址?或者它仍然显示为0.0.0.0。您可以从c代码中收到的数据包中获取源地址和目标地址。因此,如果使用环回接口,则目标地址将是127.0.0.1而不是0.0.0.0,源地址也将是127.0.0.1,以便打印连接:%s\n,inet\u ntoaclient\u addr.sin\u addr;显示实际远程地址是无效的调用?所以这取决于我的机器?它在任何情况下都会显示0.0.0.0,或者只在环回中显示?@FabioCarello我不这么认为。毕竟,您有一个特殊的情况,您自己在本地机器上工作。所以这取决于我的机器?它在任何情况下都会显示0.0.0.0,或者只在环回中显示?@FabioCarello我不这么认为。毕竟,您有一个特殊的情况,您自己在本地计算机上工作。只需将其声明为socklen\u t并将其正确设置为结构的大小,我就得到了预期的值:Connected with:127.0.0.1。谢谢!我完全忘了初始化它!我也得到了期望值!只需将其声明为socklen\u t并将其正确设置为结构的大小,我就可以得到预期的值:Connected with:127.0.0.1。谢谢!我完全忘了初始化它!我也得到了期望值!也见也见