如何否认客户'在socket编程中正确连接?

时间:2014-04-30 03:13:39

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

现在,当少于4个客户端连接时,此代码段正常工作,但是当第5个客户端连接时,正如您所看到的, for 循环中不会接受它,这会导致这样的问题:在 while 的以下循环中,select()调用继续返回 rset_conn _ 集中的 sock _ 位 - 只是因为我不接受!!

我意识到我不应该在 for 循环中忽略它(不接受),但是如何通过告诉内核&#34来正确处理它;我不想要接受这个客户,所以不要告诉我这个客户想再联系我了!&#34;?

任何帮助将不胜感激..

更新

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

3 个答案:

答案 0 :(得分:5)

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

  

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

您可以停止立即调用选择。当客户端断开连接时,再次开始调用select。只提出你想要答案的问题。

答案 1 :(得分:3)

没有套接字API来告诉内核忽略挂起的连接(在Windows上,WSAAccept()中有回调,但这是Microsoft特定的扩展名。)

在大多数平台上,您必须:

    当阵列填满时,
  1. close()监听套接字,然后在客户端断开连接时重新打开它。

  2. accept()客户端,但如果数组已满,则立即close()

  3. 在阵列已满时停止呼叫select()accept()。积压中的任何客户端最终都会超时,除非您的阵列填满,并且accept()待处理的客户端超时之前。

答案 2 :(得分:2)

当有四个现有客户端时,您可以从readFD中删除侦听套接字,并在一个客户端丢弃时将其放回,但我不明白这一点。为什么只有四个客户?为什么不删除限制并消除整个问题?真正的服务器不是以这种方式构建的。