我正在寫一個客戶端和服務器,通過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