Сообщение асинхронной передачи между двумя клиентами - PullRequest
0 голосов
/ 02 декабря 2011

На этот раз я кодирую чат-сервер и клиент. Идея такова.

Сервер использует метод select с readfd (FD_SET) для поиска, кому из подключенных на нем клиентов есть что отправить. Если он что-то находит, он отправляет это остальным клиентам.

Вот функция выбора на сервере и часть кода сервера .

SelectResults = select(maxDescriptor+1,&BackUpfdread,NULL,NULL,&time);

Я также использую функцию выбора в клиенте, чтобы он искал входящие и исходящие сообщения (те, которые сервер отправляет от других клиентов, и те, которые этот клиент хочет отправить).

Хорошо, клиент в функции выбора имеет fdread и fdwrite (FD_SET).

Здесь - это часть кода, которую клиент имеет для соединения и для чата.

Проблема в том, что если я соединяю двух клиентов на сервере, передача сообщений не происходит одновременно, а это означает, что клиенты не могут общаться в чате правильно.

Наконец-то я подумал об использовании потоков на сервере. Одна нить для ожидания получения и одна для отправки клиентам, но я хочу услышать и ваше мнение.

1 Ответ

0 голосов
/ 02 декабря 2011

В клиенте вам не нужен этот цикл от 0 до maxDescriptor.Просто проверьте, установлен ли ConnectSocket.Примерно так:

// Main loop starts here
for(; ;)
{
  memset(SentBuff, 0, sizeof(SentBuff));
  printf("Write: ");
  gets_s(SentBuff, sizeof(SentBuff));

  // Copy the fdread into BackUpfdread and fdwrite to BackUpfdwrite.
  BackUpfdread = fdread;
  BackUpfdwrite = fdwrite;

  SelectResults = select(maxDescriptor+1,&BackUpfdread,&BackUpfdwrite,NULL,&timer);

  if(SelectResults == -1)
  {
    perror("Client-select() error!\n");
    exit(1);
  }

  if (FD_ISSET(ConnectSocket, &BackUpfdread))
  {
    RecvBytes = recv(ConnectSocket, RecvBuff, sizeof(RecvBuff), 0);
    if(RecvBytes > 0)
    {
      printf("%s\n",RecvBuff);
      // Cleaning the Receive Buffer
      memset(RecvBuff,0,sizeof(RecvBuff));
    }
  }

  if (FD_ISSET(ConnectSocket, &BackUpfdwrite))
  {
    SentBytes = send(ConnectSocket, SentBuff,sizeof(SentBuff),0);
    // Cleaning the Sent Buffer
    memset(SentBuff,0,sizeof(SentBuff));
  }
} // Main loop ends here

Также не забудьте проверить наличие ошибок send и recv.Особенно важно recv, так как это вызов, который сообщит вам, что сервер отключен.

Редактировать: Еще одна важная вещь, которую следует отметить, это то, что сокет может быть доступен для записи всегда, поэтомудобавьте проверку, если есть что написать, прежде чем проверять, доступен ли сокет для записи.

...