2013-09-28 35 views
2

這只是一個簡單的聊天程序,其中echoclient發送數據到echoserver。在給我們的例子代碼中,爲什麼當我使用IP地址xxx.xxx.xxx.xxx(其中xxx的範圍是0-255,例如123.124.12.1)時,客戶端不會連接,但它會如果我輸入隨機數字,如12312或23423?在這種情況下,當我打印網絡訂購的IP,它給TCP C:客戶端未使用您輸入的IP地址進行連接?

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

我讀到127.0.0.1是環回IP地址爲本地主機。但我的問題是,爲什麼客戶端只與該地址連接?

當我運行./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; 
} 

預先感謝您!

+0

多個問題屬於中,那麼,多個問題,每個都有自己的相關示例代碼等。通常,您的任何問題越容易閱讀和回答,您就越有可能得到答案。 (另外,我真的不知道你最後一段的剩餘部分是什麼意思。) – millimoose

+0

然後編輯我的問題。 =)對不起,如果最後一段帶來混亂。那麼我只需要回答我的第一個問題。我真的不知道我是否對TCP客戶端正確地做了正確的事情。我真的需要一些啓發。 – ingenieria

回答

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,看看哪些地址響應)

+0

感謝您的回覆! =)後續問題,但是:你的意思是「其他事情發生在該主機上的端口54322上聽」?例如,如果我想讓這個代碼接受多個客戶端,我如何讓每個客戶端的ip地址彼此不同?或者我必須? (基本上我只是想區分一個客戶端和另一個客戶端)我只需要一般的想法,還是需要爲此發佈一個單獨的線程?再次感謝! =)) – ingenieria

+0

@ingenieria您不需要使每個IP地址都不同。 5個屬性定義了一個TCP套接字:源IP地址,目標IP地址,源端口,目的端口和協議(TCP)。如果您將客戶端從本地主機連接到本地主機上的服務器到目標端口54322. TCP堆棧將爲客戶端選擇一個隨機源端口。但您需要同時處理連接,例如在單獨的線程中或通過使用例如select()或poll() – nos

+0

我的意思是「其他事情發生在端口54322上」,是你試圖連接到IP 123.123.12.1,它可能是某個計算機的某個地方,也許他們運行的是端口54322在這種情況下,連接可能會成功。 – nos