блокировка select() из нескольких сокетов

Вопрос по Unix/C.

У меня есть несколько сокетов, которые я пытаюсь опрашивать для получения периодических данных. Я не хочу, чтобы select ждал бесконечно, поэтому у меня есть тайм-аут, и я работаю в цикле. Я обнаружил, что когда сокет готов к чтению , он всегда готов к чтению . Например, я не могу выбрать переход в спящий режим, когда нет данных для чтения из любого из сокетов.

for (i = 0; i < n_connections; i++) {
  FD_SET( sockfd[i], &master );
  if (sockfd[i] > fdmax) 
    fdmax = sockfd[i];
  }

for(;;) {
  int nready = 0;
  timeout.tv_sec  = 1;
  timeout.tv_usec = 0;
  read_fds = master;
  if ( (nready = select(fdmax+1, &read_fds, NULL, NULL, NULL)) == -1 ) {
    fprintf( stderr, "Select Error\n" );
    return FAILURE;
  }
  printf( "Number of ready descriptors: %d\n", nready );

  for (i = 0; i <= fdmax; i++) {
    if (FD_ISSET(i, &read_fds)) {
      if (( nbytes = recv(i, buf, sizeof(buf), 0)) <= 0 ) {
        if (nbytes == 0) {
          //connection closed
          printf("Socket %d hung up\n", i );
        }
        else {
          fprintf( stderr, "Recv Error %d\n", nbytes);
        }
      }
    else {
      printf( "Data Received on %d: %s\n", i, buf );
    }
  }
} // end file descriptor loop

Кажется, что после моего первого чтения тайм-аут в 1 секунду больше не применяется, и сокет всегда «готов к чтению», даже если доступно 0 байтов. Как я могу заставить select спать до тех пор, пока не поступят данные (на одну секунду или переключив последний аргумент на NULL, бесконечно ожидая поступления данных в сокет?)

Вывод:

Number of Ready Descriptors: 2
Data Received on 4: GreetingsChap
Data Received on 5: HiMatengsChap
Loop...
Number of Ready Descriptors: 2
Socket 4 hung up
Socket 5 hung up
Loop...
Number of Ready Descriptors: 2
Socket 4 hung up
Socket 5 hung up
Loop...

Спасибо,

Примечание. Код обновлен для ясности. Обновлено на основе предложений @yvesBraumes - все еще не работает.

6
задан RootsAmongRuins 5 March 2012 в 22:10
поделиться