2017-02-01 119 views
0

我想创建一个客户端并将其连接到服务器。我知道客户端进程在服务器之前开始运行,所以我在无限循环中进行连接,直到它接受为止。然后我想输入消息给客户端并发送给服务器,服务器会在屏幕上打印它们。我删除了代码中的所有错误检测,使其更短,我知道他们必须在那里。我试图这样做,但服务器收不到任何东西,客户端不能做第二次连接。C posix套接字,无法将数据从客户端发送到服务器

服务器

int main(int argc, char *argv[]) 
{ 
    int sockfd, newsockfd; 
    socklen_t clilen; 
    char buffer[256]; 
    struct sockaddr_in serv_addr, cli_addr; 
    sockfd = socket(AF_INET, SOCK_STREAM, 0); 
    serv_addr.sin_family = AF_INET; 
    serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); 
    serv_addr.sin_port = htons(5000); 
    bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)); 
    listen(sockfd, 5); 
    clilen = sizeof(cli_addr); 
    while (newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr,&clilen) >= 0) 
    { 
     read(newsockfd, buffer, 255); 
     close(newsockfd); 
    } 
    close(sockfd); 
    return 0; 
} 

客户

int main(int argc, char *argv[]) 
    { 
    int sockfd; 
    struct sockaddr_in serv_addr; 

    char buffer[256]; 
    sockfd = socket(AF_INET, SOCK_STREAM, 0); 
    serv_addr.sin_family = AF_INET; 
    serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); 
    serv_addr.sin_port = htons(5000); 
    while (1) { 
     while ((connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)) { 
      printf("trying to connect\n"); 
      sleep(1); 
     } 
     printf("connected\nplease, enter a message\n"); 
     scanf("%s", buffer); 
     write(sockfd, buffer, strlen(buffer)); 
    } 
    close(sockfd); 
    return 0; 
} 
+0

一旦'connect()'失败,就不能保证它可以在同一套接字上再次被调用。通常最好在每个connect()尝试中销毁并重新创建套接字。然而,无论哪种方式,一旦'connect()'成功,在下一次循环迭代中再次调用'connect()'之前,客户端不会关闭连接的套接字。 –

+0

如果您从代码中删除所有错误处理,您怎么可能期望能够调试它?这不是一个合理的策略。在你提供一个错误代码之前,它也不是一个可以回答的问题,直到你把错误处理回来,你才能这样做。直到同上之前,您无法证明没有错误代码。 – EJP

回答

2

我不只是知道你是如何编译你的代码,但如果你已经设置了警示标志(gcc中的-Wall)你会得到这个警告

server.c: In function ‘main’: 
server.c:33:44: warning: suggest parentheses around assignment used as truth value [-Wparentheses] 
if (newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr,&clilen) >= 0) { 

通过其代理,我变了,这个..

if (newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr,&clilen) >= 0) { 

要..(注意额外的括号)

if ((newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr,&clilen)) >= 0) { 

我没有更多的额外的警告,并且服务器抓客户的消息。

下面是在调试这个我跑的服务器(这基本上是有轻微的改变你的代码)

int sockfd, newsockfd; 
socklen_t clilen; 
char buffer[256]; 
int nbytes = 0; 
struct sockaddr_in serv_addr, cli_addr; 
sockfd = socket(AF_INET, SOCK_STREAM, 0); 
serv_addr.sin_family = AF_INET; 
//serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); 
serv_addr.sin_addr.s_addr = INADDR_ANY; 
serv_addr.sin_port = htons(5007); 
bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)); 


if (listen(sockfd, 5) <0) { } 

clilen = sizeof(cli_addr); 
if ((newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr,&clilen)) >= 0) { 

    while ((nbytes = read(newsockfd, buffer, sizeof(buffer)))<0) { 
     sleep(1); 
    } 

    printf("client sent: %s", buffer); 
} 
close(newsockfd); 
close(sockfd); 
return 0; 
0

另一个问题是,我们有我们每次做客户端连接,如时间创建套接字:

while (1) { 
    sockfd = socket(AF_INET, SOCK_STREAM, 0); 
    while ((connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)) { 
     printf("trying to connect\n"); 
     sleep(1); 
    } 
    printf("connected\nplease, enter a message\n"); 
    scanf("%s", buffer); 
    write(sockfd, buffer, strlen(buffer)); 
} 
+0

你应该只有一个套接字并重用它(除非你想同时连接到多个服务器点) 你也没有正确地从while循环中断,所以你将永远没有机会正确地关闭你的套接字。它会伤害你的测试,因为你必须等待操作系统在你退出后释放那个端口 – svarog

相关问题