如何在套接字编程中正确拒绝客户端的连接?

cli*_*i__ 1 c sockets linux tcp

我有一个程序作为一个简单的TCP服务器,它将接受并服务多达4个客户端.我编写了以下代码片段来存档这个目标,更清楚的是,我用"魔术数字"替换了一些MACRO.

while(1) {
  int ret = 0;
  ///
  // sock_ is the listening socket, rset_conn_ only contains sock_
  //
  if(select(sock_ + 1, &rset_conn_, NULL, NULL, &timeo_) <= 0) {
    ret = 0;
  }

  if(FD_ISSET(sock_, &rset_conn_)) {
    ret = 1;
  }

  /// 
  // because the rule select() clears file descriptor and updates timeout is 
  // complex, for simplicity, let's reset the sock_ and timeout
  //
  FD_SET(sock_, &rset_conn_);
  timeo_.tv_sec = 0;
  timeo_.tv_usec = 500000;

  if(! ret) {
    continue ;
  }

  ///
  // csocks_ is an 4 integer array, used for storing clients' socket
  //
  for(int i = 0 ; i < 4 ; ++i) {
    if((-1 == csocks_[i]) && (-1 != (csocks_[i] = accept(sock_, NULL, NULL)))) {
      break ;
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

现在,当小于4个客户端连接,这个代码片断工作正常,但在第5客户端连接,你可以看到,它不会在接受循环,这导致了这样一个问题:在下面的循环,而,select()调用一直在rset_conn_ set中使用sock_位返回---只是因为我不接受它!

我意识到我不应该在for循环中忽略它(不接受),但是如何通过告诉内核"我不想接受这个客户端来正确处理它,所以不要告诉我这个客户端想要连接我更多!"?

任何帮助将不胜感激..

更新:

我无法停止调用select()调用,因为已经连接的客户端可能断开连接,然后我的程序将有新的客户端空间.我需要继续监听套接字以接受连接,而不是在达到一点时停止监听.

Dav*_*rtz 5

你为什么问一个你不想要答案的问题?select如果您不想被告知存在未接受的连接,请停止呼叫侦听套接字.

我无法停止调用select()调用,因为已经连接的客户端可能断开连接,然后我的程序将有新的客户端空间.我需要继续监听套接字以接受连接,而不是在达到一点时停止监听.

现在可以停止呼叫选择.当客户端断开连接时,再次开始呼叫select.只提出你想要答案的问题.

  • `accept` /`close`.不要忘记将侦听套接字设置为非阻塞! (4认同)