2013-10-03 3 views
1

По какой-то причине FD_ISSET всегда возвращает значение true для & wfds, даже если отправлять нечего. Вот фрагмент кода (тот же как на клиенте, так и на сервере). Как клиент, так и сервер получают такую ​​же проблему, когда выбирают высказывание wfds. Должен ли он активироваться только при вводе сообщения на клавиатуре и нажатии клавиши ввода?Выберите c: wfds всегда включается, вызывая блок

while (1) { 
      //trying select.. 
      tv.tv_sec = 29; 
      tv.tv_usec = 500000; 
      FD_ZERO(&rfds); 
      FD_ZERO(&wfds); 
      FD_SET(new_sockfd, &rfds); 
      FD_SET(new_sockfd, &wfds); 

      n = select(new_sockfd + 1, &rfds, &wfds, NULL, &tv); 

      if (n > 0) { 
       if (FD_ISSET(new_sockfd, &rfds)) { 

        while (1) { 
         if ((num = recv(new_sockfd, buffer, 10240, 0)) == -1) { 
          //fprintf(stderr,"Error in receiving message!!\n"); 
          perror("recv"); 
          exit(1); 
         } else if (num == 0) { 
          printf("Connection closed\n"); 
          return 0; 
         } 
         buffer[num] = '\0'; 
         printf("Message received: %s\n", buffer); 
         break; 
        } 
       } 
       //this always returns true on client and host 
       if (FD_ISSET(new_sockfd, &wfds)) { 

        while (1) { 
         fgets(buffer, MAXDATASIZE - 1, stdin); 
         if ((send(new_sockfd, buffer, strlen(buffer), 0)) == -1) { 
          fprintf(stderr, "Failure Sending Message\n"); 
          close(new_sockfd); 
          exit(1); 
         } else { 
          printf("Message being sent: %s\n", buffer); 
          break; 
         } 
        } 
       } 
      } 
     } 

ответ

1

Возможно, вы неправильно поняли, как работает параметр writefds для выбора().

Вы должны установить флаг в writefds для дескриптора файла, прежде чем вызывать select(), если и только если у вас есть что отправить.

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

 Смежные вопросы

  • Нет связанных вопросов^_^