C中的套接字,使用select()方法的非阻塞send()和recv()

时间:2016-02-23 04:08:07

标签: c sockets tcp ip

我想用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
          }
        }
      }
    }
  }

1 个答案:

答案 0 :(得分:0)

您的第一个for循环需要在send()调用后终止,然后您应该启动另一个来处理选择和接收。

您需要检查recv()返回零和-1,然后关闭套接字并将其从FD集中移除。

您还需要在j <= P时循环播放。