C:超时的非阻塞套接字:如何避免繁忙等待?

时间:2015-03-03 17:53:47

标签: c sockets signals server nonblocking

以下代码允许服务器等待客户端连接到(已绑定的)套接字。 它在客户端连接到套接字时终止,或者当“server_run”取值0时终止:这允许代码的其他部分在适当时关闭服务器。

static inline int wait_for_client_to_connect(int sockfd, int* server_run){                                                                                                                                                                                  
  int client_found = 0;                                                                                                                                                                                                                                        
  int clientfd = 0;                                                                                                                                                                                                                                            
  struct sockaddr_in client_addr;                                                                                                                                                                                                                              
  int addrlen=sizeof(client_addr);                                                                                                                                                                                                                             
  if ( listen(sockfd,1) != 0 ) return -1;                                                                                                                                                                                                                      
  while ( client_found==0 && *server_run==1 ) {                                                                                                                                                                                                                 
    clientfd = accept(sockfd, (struct sockaddr*)&client_addr, &addrlen);                                                                                                                                                                                       
    if ( clientfd < 0 ) {                                                                                                                                                                                                                                      
      clientfd = 0;                                                                                                                                                                                                                                            
      if (errno==EAGAIN || errno==EWOULDBLOCK) usleep(10); // nobody connected, wait for request                                                                                                                                                               
      else return -1; // something wrong, send error                                                                                                                                                                                                           
    } else { // client found, configuring socket and exit                                                                                                                                                                                                      
      client_found=1;                                                                                                                                                                                                                                          
      int nodelay_flag = 1;                                                                                                                                                                                                                                    
      setsockopt(clientfd, IPPROTO_TCP, TCP_NODELAY, (void*) &nodelay_flag, sizeof(int)); // disable nagle algorithm                                                                                                                                           
    }                                                                                                                                                                                                                                                          
  }                                                                                                                                                                                                                                                            
  return clientfd;                                                                                                                                                                                                                                             
}                    

根据对其他帖子(C : non blocking sockets with timeout : how to check if connection request was made?)的回答和评论,这不是要走的路,因为它涉及繁忙的等待。

E.g。评论说:

  

“使用阻塞IO处理关闭的标准方法是使用a   信号处理程序设置关闭标志,然后检查标志时   listen返回-1,并将errno设置为EINTR“

我很不清楚上面的代码如何适应“使用信号处理程序”....

1 个答案:

答案 0 :(得分:0)

你想在套接字上select(),如果它已准备好阅读,只需acceptselect()有一个超时,所以你可以永远等待,或者在每个循环中等待一两秒,因为select会在FD准备好后立即退出(这里准备好了阅读&#39;表示准备接受&#39;)。