具有多个客户端的服务器 - 使用select()编写

时间:2011-12-29 23:01:15

标签: c++ sockets asynchronous

我正在尝试编写一次处理多个客户端的服务器。显然我应该使用select。我找到了很多教程,但没有一个能够处理写作。

我知道我应该如何阅读数据,但是在我的'循环'中处理写回客户端的适当方式是什么?

提前致谢。

2 个答案:

答案 0 :(得分:3)

如果您有要发送到特定套接字的数据,那么当该套接字的输出缓冲区中有可用空间时,您需要select()返回。告诉select()执行此操作的方法类似于仅使用select()进行读取 - 除了您还在第二个fd_set对象上执行FD_SET。

int socks[10] = {... some client sockets...}

while(1)
{
   fd_set readSet, writeSet;

   FD_ZERO(&readSet);
   FD_ZERO(&writeSet);

   int maxSock = -1;
   for (int i=0; i<10; i++)
   {
      FD_SET(socks[i], &readSet);
      if (socks[i] > maxSock) maxSock = socks[i];

      if (IHaveDataToSendToThisSocket(i))  // implement this function as appropriate to your program
      {
         FD_SET(socks[i], &writeSet);
         if (socks[i] > maxSock) maxSock = socks[i];
      }
   }

   int ret = select(maxSock+1, &readSet, &writeSet, NULL, NULL);
   if (ret < 0)
   {
      perror("select() failed");
      break;
   }

   // Do I/O for sockets that are ready
   for (int i=0; i<10; i++)
   {
      if (FD_ISSET(socks[i], &readSet))
      {
         // there is data to read on this socket, so call recv() on it
      }

      if (FD_ISSET(socks[i], &writeSet))
      {
         // this socket has space available to write data to, so call send() on it
      }
   }
}

答案 1 :(得分:0)

实际上,我认为你想使用poll()而不是select(),但这是重点。要写入多个客户端,请确保不使用阻止写入。您可能无法检测特定内容是否可以消化更多数据,因此在编写时可能不需要使用poll()(或select())。但是,如果您想为使用不同速度数据的客户做好准备,您可能希望在客户端消化更多数据时接收通知。

除此之外,poll()或select()可以通知读缓冲区中可用的数据或写缓冲区中可用的空间。除了需要设置不同的标志外,其用途几乎相同。