2013-09-28 36 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