我正在写一个客户端和服务器,通过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");
}
}
}
a)'recvfrom' &&'sendto' =='UDP' b)'UDP' &&'第一个查询到服务器没有被客户端接收到,不像其他的.' =='不是error'。 ...如果你想要可靠的通信,使用TCP或自己实现它或使用一些lib或... – deviantfan 2015-04-03 16:15:28
关闭()后调用perror()这不是一个可靠的顺序,当试图显示select()建议颠倒perror的顺序并关闭语句 – user3629249 2015-04-03 16:41:33
建议在select()(最后一个参数)上放置超时并检查时间是否过期。发生超时时,循环返回以再次发送字符串。请记得'刷新'超时变量作为一些操作系统(linux想到)修改该变量 – user3629249 2015-04-03 17:02:40