2013-10-03 34 views
1

由於某些原因,FD_ISSET對於& wfds始終返回true,即使沒有任何要發送的內容。這是代碼片段(在客戶端和服務器上都是一樣的)。選擇說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參數適用於select()。

您應該在調用select()函數之前爲您的文件描述符設置標誌writefds,當且僅當您有要發送的內容時。

然後當套接字緩衝區中有足夠的空間接受要發送的數據時,select()返回,並在writefds中設置了標誌left。然後你檢查那個標誌,並且意識到套接字是可用於發送,並且你也知道你有東西要發送,因爲最初是你,在調用select()之前誰設置了標誌。因此您可以繼續通過套接字發送數據。然後,如果您發送了所有的數據,並且您的待發送緩衝區爲空,則在您下次調用select()時,將保留標誌writefds