我想用select()和FD_ISSET()创建一个非阻塞的send()和recv()。我遇到了这种行为,其中FD_ISSET()对于第一个套接字是真的,并且所有其他套接字总是没有准备好。我很困惑,为什么会这样,我想知道我是否正确使用select()。
如果我发送了100个请求,最终除第一个之外的一个套接字将准备好recv(),但我没有得到这种行为。
for(int i = 0; i < P - 1; i++) {
sockArr[i] = GetSocket(server, port);
if (sockArr[i] < 0) {
// handle error
}
fcntl(sockArr[i], F_SETFL, O_NONBLOCK);
if(sockArr[i] > maxfd) {
maxfd = sockArr[i];
}
}
fd_set sockSet;
for(int i = 0; i < P - 1; i++) {
numBytes = send(sockArr[i], request, requestLen, 0);
if (numBytes < 0 || numBytes != requestLen) {
// handle error
}
// read from other stackoverflow post you need to rest
// per select() call
FD_ZERO(&sockSet);
for(int i = 0; i < P - 1; i++) {
FD_SET(sockArr[i], &sockSet);
}
if(select(maxfd+1, &sockSet, NULL, NULL, NULL)) {
for(int j = 0; j < i; j++) {
if(FD_ISSET(sockArr[j], &sockSet)) { // <------ only true for j = 0
numBytes = recv(sockArr[j], buffer, MAXBUFLEN - 1, 0);
if (numBytes < 0) {
// handle error
}
}
}
}
}
答案 0 :(得分:0)
您的第一个for
循环需要在send()
调用后终止,然后您应该启动另一个来处理选择和接收。
您需要检查recv()
返回零和-1,然后关闭套接字并将其从FD集中移除。
您还需要在j <= P
时循环播放。