2

これは、echoclient がデータを echoserver に送信する単純なチャット プログラムです。提供されたサンプル コードでは、IP アドレス xxx.xxx.xxx.xxx (xxx の範囲は 0 ~ 255、たとえば 123.124.12.1) を使用するとクライアントが接続しないのはなぜですか。 12312 や 23423 などの乱数を入力すると? この場合、ネットワークで注文したIPを印刷すると、次のようになります

Network ordered ip(client side): 00000000
Network ordered ip(server side): 127.0.0.1.

localhost のループバック IP アドレスである 127.0.0.1 について読みました。しかし、私の質問は、クライアントがそのアドレスにのみ接続するのはなぜですか?

を実行する./echoclient 12312と、クライアントが接続し、プログラムが正常に機能します。しかし、実行する./echoclient 123.123.12.1と、クライアントは接続しません。

..または、間違った方法で接続していますか?

コードは次のとおりです。

echoserver.c

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>



int main(int argc, char **argv)
{
  int listenfd,connfd;
  struct sockaddr_in servaddr,cliaddr;
  socklen_t len = sizeof(cliaddr);
  char cli_ip[32];
  char mesg[1024];

  listenfd = socket(PF_INET,SOCK_STREAM,0);
  bzero(&servaddr, sizeof(servaddr));
  servaddr.sin_family = AF_INET;
  servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
  servaddr.sin_port = htons(54322);
  if ( bind( listenfd, (struct sockaddr*) &servaddr, sizeof(servaddr) ) < 0 ){
      perror(NULL);
      exit(-1);
  }

  //not present in udp server
  listen(listenfd,2);

  while(1){
      //not present in udp server
    connfd = accept(listenfd,(struct sockaddr *)&cliaddr,&len);
    inet_ntop(AF_INET,(struct in_addr *) &cliaddr.sin_addr, cli_ip, sizeof(cli_ip) );
    printf("Client %s connected. \n",cli_ip);     
    while(1){
      memset(mesg,0,sizeof(mesg));
      if( recvfrom(connfd,mesg,sizeof(mesg),0,(const struct sockaddr *)&cliaddr,&len) > 0 ){
            printf("From %s port %d: %s",cli_ip,ntohs(cliaddr.sin_port),mesg);
      }
      else {
        printf("Client %s disconnected. \n",cli_ip);      
        break;
      }
    }
    close(connfd);
  }
  close(listenfd);
  return 0;
}

echoclient.c

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>



int main(int argc, char **argv)
{
  int sockfd;
  struct sockaddr_in servaddr;
  socklen_t len = sizeof(servaddr);
  char mesg[1024];

  if(argc!=2){ 
      printf("Usage: %s <ip_addr>\n",argv[0]);
      exit(1);
  }

  sockfd = socket(PF_INET,SOCK_STREAM,0);
  bzero(&servaddr, sizeof(servaddr));
  servaddr.sin_family = AF_INET;
  servaddr.sin_port = htons(54322);
  inet_pton(AF_INET,argv[1],&servaddr.sin_addr);
  //printf("Network ordered ip: %08x\n",servaddr.sin_addr.s_addr);

  //not present in udp clients
  connect(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr));

  while(1){
    fgets(mesg,sizeof(mesg),stdin);
    sendto(sockfd,mesg,strlen(mesg),0,(const struct sockaddr *)&servaddr,len);
  }
  close(sockfd);
  return 0;
}

前もって感謝します!

4

1 に答える 1

2

無効なアドレスを入力すると12312、inet_pton は失敗します。でアドレスをゼロにしたservaddrので、IP アドレスは 0.0.0.0 です。0.0.0.0 は「このホスト」として解釈されます。サーバーは、実行中のホスト上の任意のアドレスをリッスンするように設定されています。

また、クライアントと同じホストでサーバーを実行すると、クライアントがクライアントを実行しているホストに接続するため、接続を確立できます。

123.123.12.1 などの有効なアドレスを入力した場合、そのホストでサーバーを実行するか、そのホストのポート 54322 でリッスンする何かが発生しない限り、当然、そのホストへの接続は成功しません。

(0.0.0.0 は、ホストのループバック アドレスにルーティングされることがよくあります。たとえばping 0.0.0.0、応答するアドレスを確認することができます)

于 2013-09-28T21:18:12.897 に答える