1

ローカルホストアドレスを使用して、クライアントサーバーの単純な実装をテストしようとしています。これがコードです。

サーバ:

/*
 * 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);        
   }

   /*...*/

}

2つの異なる端末で実行すると、サーバーから次のメッセージが返されます。

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

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

初期化されていないaccept()に3番目のパラメーターを渡しているようです。これは、2番目のパラメーターのサイズに設定する必要があります。それに加えて、intではなくsocklen_tである必要があります。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
server_addr.sin_addr.s_addr = INADDR_ANY;

おそらく

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