Сервер с несколькими клиентами - запись с помощью select () - PullRequest
1 голос
/ 30 декабря 2011

Я пытаюсь написать сервер, который обрабатывает несколько клиентов одновременно.Видимо, я должен использовать select.Я нашел множество учебных пособий, но ни одно из них не касается записи.

Я понимаю, как я должен читать данные, но каков ... подходящий способ обработки обратной записи клиентам в моем «цикле»?

Заранее спасибо.

Ответы [ 2 ]

3 голосов
/ 30 декабря 2011

Если у вас есть данные, которые вы хотите отправить в конкретный сокет, то вам нужно выбрать 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
      }
   }
}
0 голосов
/ 30 декабря 2011

На самом деле, я думаю, что вы хотите использовать poll (), а не select (), но это не главное.Для записи нескольким клиентам вы хотите убедиться, что вы не используете блокирующие записи.Возможно, вам не удастся определить, может ли конкретный пользователь переварить больше данных, и, таким образом, вам может не понадобиться использовать poll () (или select ()) при записи.Однако, если вы хотите быть готовым к тому, что клиенты используют данные с разной скоростью, вы можете получать уведомления, когда клиент может переварить больше данных.

Кроме этого, poll () или select () могут уведомлять обаданные доступны в буфере чтения или в буфере записи.Использование практически такое же, за исключением того, что вам нужно установить другой флаг.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...