2015-04-03 132 views
1

我正在写一个客户端和服务器,通过Unix域套接字进行通信(对于POSIX开发类中的任务,只是为了学习这个概念)。会发生什么是客户端发送命令到服务器,并且服务器解析它们并以答案回应。我的问题是,第一个查询到服务器不被客户端接收,不像其他人。什么可能导致select()不返回?

更清楚的是,客户端没有接收到给定服务器实例的第一个查询,如果我关闭客户端实例并打开一个新实例,则会收到第一个查询。它只发生在服务器实例的第一个查询中。

我附上了客户端的代码的相关部分,服务器作为基于select()的服务器。

memset(&control, 0, sizeof(control)); 
control.sun_family = AF_UNIX; 
strcpy(control.sun_path, CLIENT_PATH); 

bind(sockfd, (struct sockaddr *)&control, sizeof(struct sockaddr_un)); 

memset(&server, 0, sizeof(server)); 
server.sun_family = AF_UNIX; 
strcpy(server.sun_path, SERVER_PATH); 

while(1) { 
FD_ZERO(&readfds); 
FD_SET(sockfd, &readfds); 
FD_SET(STDIN, &readfds); 

    if (select(sockfd+1, &readfds, NULL, NULL, NULL) < 0) { 
     close(sockfd); 
     perror("control: select"); 
     exit(1); 
    } 

    if (FD_ISSET(sockfd, &readfds)) { 
     if ((nbytes = recvfrom(sockfd, buf, sizeof(buf), 0, NULL, NULL)) < 0) { 
      perror("recv"); 
     } 
     buf[nbytes] = '\0'; 
     printf(">> %s", buf); 
    } 

    if (FD_ISSET(STDIN, &readfds)) { 
     nbytes = read(STDIN, buf, sizeof buf); 
     buf[nbytes] = '\0'; 
     if (sendto(sockfd, buf, strlen(buf), 0, 
       (struct sockaddr *)&server, sizeof(struct sockaddr_un)) < strlen(buf)) { 
      perror("send"); 
     } 
    } 
} 
+2

a)'recvfrom' &&'sendto' =='UDP' b)'UDP' &&'第一个查询到服务器没有被客户端接收到,不像其他的.' =='不是error'。 ...如果你想要可靠的通信,使用TCP或自己实现它或使用一些lib或... – deviantfan 2015-04-03 16:15:28

+1

关闭()后调用perror()这不是一个可靠的顺序,当试图显示select()建议颠倒perror的顺序并关闭语句 – user3629249 2015-04-03 16:41:33

+0

建议在select()(最后一个参数)上放置超时并检查时间是否过期。发生超时时,循环返回以再次发送字符串。请记得'刷新'超时变量作为一些操作系统(linux想到)修改该变量 – user3629249 2015-04-03 17:02:40

回答

0

参见手册页:http://linux.die.net/man/2/select。 “如果超时时间为NULL(无超时),则选择()可以无限期阻止。”您将它指定为NULL(select()的最后一个参数),然后select()将会阻塞,直到套接字准备就绪。

所以你需要做的是分配一个结构timeval超时。 0秒0 usec timeout表示立即返回,正值表示有套接字准备使用(在您的情况下用于读取)或超时时返回。

+0

目前还不清楚,为select()添加一个超时将会做任何事情来解决他的潜在问题,即预期的查询数据没有被接收到。 – 2015-04-03 21:35:15

+0

@JeremyFriesner,我同意。我正在检查数据是从服务器发送的,并且确实是发送的。 – Quaker 2015-04-03 22:00:04

+0

我将超时设置为0,问题保持不变。我开始认为这可能是事实,我'recvfrom()',然后使用有关发件人的详细信息'sendto()'查询答案。 – Quaker 2015-04-04 07:49:05

相关问题