c - 在监听套接字上使用 select()

标签 c linux sockets 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;
}

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

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;
} 

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

最佳答案

这必须在每次迭代中:

FD_ZERO(&rfds);
FD_SET(fd, &rfds);

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

关于c - 在监听套接字上使用 select(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42578567/

相关文章:

linux - 在 Tkinter 脚本中运行终端命令

c - 可能出了什么问题, ls 在我自己的 shell 上不起作用

linux - 在 Sublime Text 中,如何查找和替换文件名

C : cost of copying data from heap to stack?

linux - 不可预测的警报忽略信号

java - 如何使用java套接字编程解码C结构(如数据包)

python - 从服务器 python 向客户端发送连续数据

java - java套接字读取的数据是否与发送时完全相同

c - 父进程在设置 SIGCHLD 时被阻塞

c - 是否可以将文件下载到指定目录?