Zah*_*tar 1 c sockets loops posix-select
我有一个客户端和服务器,客户端运行一个select循环以在TCP和UDP连接之间进行多路复用。我正在尝试将我的TCP连接文件描述符同时添加到read和write集中,然后使用writeset和1使用readset 发起一个消息交换。我与设备的消息通信write正常,但与read设备无法通信。
客户代码:
char buf[256] = {};
char buf_to_send[256] = {};
int nfds, sd, r;
fd_set rd, wr;
int connect_init = 1;
/* I do the Connect Command here */
FD_ZERO(&rd);
FD_ZERO(&wr);
FD_SET(sd, &rd);
FD_SET(sd, &wr);
nfds = sd;
for(; ;){
r = select(nfds + 1, &rd, &wr, NULL, NULL);
if(connect_init == 0){
if(FD_ISSET(sd, &rd)){ // this is not working, if I change rd to wr, it works!
r = recv(sd, buf, sizeof(buf),0);
printf("received buf = %s", buf);
sprintf(buf, "%s", "client_reply\n");
send(sd, buf, strlen(buf), 0);
}
}
/* Everything below this works correctly */
if (connect_init){
if(FD_ISSET(sd, &wr)){
sprintf(buf_to_send, "%s", "Client connect request");
write(sd, buf_to_send, strlen(buf_to_send));
recv(sd, buf, sizeof(buf), 0);
printf("Server said = %s", buf);
sprintf(buf_to_send, "Hello!\n"); // client Hellos back
send(sd, buf_to_send, strlen(buf_to_send), 0);
}
connect_init = 0;
}
} // for loops ends
Run Code Online (Sandbox Code Playgroud)
每次调用之前,您都需要在循环中初始化集合select。这是必需的,因为select会对其进行修改。Beej的《网络编程指南》中有一种使用方法的综合示例select。
因此,在您的代码中,它似乎select首先返回并允许写入,但不允许读取,这会将读取位重置为0,然后没有任何东西可以将其设置为1,因为从那时起select就不会触摸它,因为它已经0。
如果selectAPI困扰您,请看一下poll,它会避免这种情况(请注意,实际/效率上可能没有差异,基本上可以归结为个人喜好)。在具有许多描述符的“真实”代码上(例如具有许多客户端的网络服务器),在性能方面,您应该使用其他机制,可能是一些更高级别的事件库,然后使用操作系统特定的系统API,例如Linux的epoll工具。但是,仅检查几个描述符select是经过尝试的,真实的且相对可移植的选择。
| 归档时间: |
|
| 查看次数: |
4967 次 |
| 最近记录: |