2014-11-02 169 views
1

我正在写一个文件共享程序,它的主旨是有一个主服务器,所有客户端连接到。但是,客户端是托管文件的机器,因此当一个客户端从另一个客户端请求文件时,它必须与它建立连接。当客户端最初与主服务器连接,我得到它的IP和端口(我认为)有:获取客户端IP地址和端口?

int client_len = sizeof(client); 
    int new_sd = accept(sd, (struct sockaddr *)&client, &client_len); 

    char str[INET_ADDRSTRLEN]; 
    inet_ntop(AF_INET, &(client.sin_addr), str, INET_ADDRSTRLEN); 
    //printf("%s\n", str); 
    int port = (int) ntohs(client.sin_port);   
    //printf("Port is: %d\n", (int) ntohs(client.sin_port)); 

的printf的的给我127.0.0.1和40XXX。主服务器使用127.0.0.1和端口3000.所以我很确定我有正确的客户端IP和端口但是当我尝试在两个使用127.0.0.1和40XXX的客户端之间建立连接时,它不起作用。连接功能不断返回一个错误。这里的代码试图建立两个客户端之间的连接:

if ((cd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { 
    fprintf(stderr, "Can't creat a socket\n"); 
     exit(1); 
    } 
    bzero((char *)&cServer, sizeof(struct sockaddr_in)); 
    cServer.sin_family = AF_INET; 
    cServer.sin_port = htons(cPort); 
    if (inet_pton(AF_INET, cAddress, &cServer.sin_addr) == -1) { 
     printf("inet_pton error occured\n"); 
     exit(1); 
    } 

    /* Connecting to the server */ 
    if (connect(cd, (struct sockaddr *)&cServer, sizeof(cServer)) == -1) { 
     fprintf(stderr, "Can't connect to server\n"); 
     exit(1); 
    } 

cPort是一个int而cAddress是一个char数组。

以下是客户端尝试为传入连接创建连接的代码。获取IP地址和端口的代码分别返回0.0.0.0和0。

if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { 
    fprintf(stderr, "Can't creat a socket\n"); 
    exit(1); 
} 

/* Bind an address to the socket */ 
bzero((char *)&clientServer, sizeof(struct sockaddr_in)); 
clientServer.sin_family = AF_INET; 
clientServer.sin_port = 0; 
clientServer.sin_addr.s_addr = htonl(INADDR_ANY); 
if (bind(sockfd, (struct sockaddr *)&clientServer, sizeof(clientServer)) == -1){ 
    fprintf(stderr, "Can't bind name to socket\n"); 
    exit(1); 
} 

char str[INET_ADDRSTRLEN]; 
inet_ntop(AF_INET, &(clientServer.sin_addr), str, INET_ADDRSTRLEN); 
printf("%s\n", str); 
int clientServerPort = (int) ntohs(clientServer.sin_port);  
printf("Port is: %d\n", (int) ntohs(client.sin_port)); 

/* queue up to 10 connect requests */ 
listen(sockfd, 10); 

所有帮助非常感谢!

回答

1

您不能将客户端端口用于新连接。该端口仅用于连接到您的服务器,它不会侦听传入的连接。客户端需要绑定另一个端口,在其上侦听并将该端口号发送给您。然后您可以将其发送到另一个客户端,并且可以连接到该端口。

还要注意,如果第一个客户端位于NAT路由器后面,这可能根本不起作用。路由器不知道它应该将这个新端口转发给客户端。当涉及到NAT时,使用动态端口号的对等应用程序是不切实际的。相反,您应该为此定义一个专用端口;那么用户可以在其路由器上为此端口配置端口转发。

+0

这就是我最初的尝试。使用上面相同的代码获取绑定后的IP地址和端口号,但它返回0.0.0.0和0.我更新了我的主帖。即使我严格遵守本地IP,NAT路由器也会影响我吗? – user2929779 2014-11-02 05:58:40

+0

如果你要通过路由器,NAT只是一个问题。如果所有机器都在路由器后面,这不是问题。 – Barmar 2014-11-02 06:00:43

+0

您需要调用'getsockname()'来获取通过'bind()'分配给套接字的IP和端口。 http://stackoverflow.com/questions/10167540/how-to-get-local-ip-and-port-in-unix-socket-programming – Barmar 2014-11-02 06:02:14