在侦听套接字上使用 select()

Jer*_*oen 2 c sockets linux select bind

我想打开一个端口并等待传入​​的连接,但是我无法开始select()工作。我可以使用它,poll()但我需要select()便携性。我究竟做错了什么?

等待连接的代码如下所示(我需要每 200 毫秒检查一次中断):

/* Wait for a descriptor */
int wait_for_fd(int fd){
  int waitms = 200;
  struct timeval tv;
  tv.tv_sec = 0;
  tv.tv_usec = waitms * 1000;
  fd_set rfds;
  FD_ZERO(&rfds);
  FD_SET(fd, &rfds);
  int active = 0;
  while(active == 0){
    active = select(fd+1, &rfds, NULL, NULL, &tv);
    bail_for(active < 0, "select()");
    if(pending_interrupt())
      break;
  }
  return active;
}
Run Code Online (Sandbox Code Playgroud)

然后我的代码实际打开一个端口并等待连接:

int open_port(int port){

  // define server socket
  struct sockaddr_in serv_addr;
  memset(&serv_addr, '0', sizeof(serv_addr));
  serv_addr.sin_family = AF_INET;
  serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
  serv_addr.sin_port = htons(port);

  //creates the listening socket
  int listenfd = socket(AF_INET, SOCK_STREAM, 0);
  bail_for(listenfd < 0, "socket()");
  bail_for(bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0, "bind()");
  bail_for(listen(listenfd, 10) < 0, "listen()");

  //each accept() is a new incoming connection
  printf("Waiting for connetion on port %d...\n", port);
  wait_for_fd(listenfd);
  int connfd = accept(listenfd, NULL, NULL);
  bail_for(connfd < 0, "accept()");
  printf("Incoming connection!\n");

  //do not allow additional client connetions
  close(listenfd);
  return connfd;
} 
Run Code Online (Sandbox Code Playgroud)

但是,wait_for_fd()即使客户端正在连接,也永远不会返回(由于 select 总是返回 0)。

Vel*_*kan 5

这必须在每次迭代中:

FD_ZERO(&rfds);
FD_SET(fd, &rfds);
Run Code Online (Sandbox Code Playgroud)

因为rfds是 的输入/输出参数select()。它实际上告诉它哪些 fds 受到影响。