2013-04-22 4 views
5

Ich schreibe ein Programm, das UDP-Nachrichten empfängt sowie die Eingabe von Benutzern jedoch meine STDIN blockiert immer noch mit wählen. Wenn ich FD_CLR die stdin fd vor Auswahl des Programms läuft gut, zeigt an, dass der stdin-Socket immer bereit ist, Daten von ihm gelesen zu haben. Ich habe versucht, ein Time-TV einzuführen, um es auszureden, aber das scheint auch nicht zu funktionieren. Sollte ich die Steckdose irgendwo schließen oder FD_CLR anrufen, wo ich nicht bin? Das Endergebnis sollte eine nicht blockierende STDIN sein, aber derzeit blockiert es. DankeWählen Sie() Blockierung auf Stdin, wird nicht Timeout

int 
wait_for_input(){ 
      fd_set fds; 
      int maxfd, sd, err, n; 
      struct sockaddr_in addr; 
      char stdbuf[BUFLEN]; 
      unsigned char udpbuf[BUFLEN]; 

      //memset(stdbuf,0x0,sizeof(stdbuf)); 
      memset(stdbuf,0x0,sizeof(udpbuf)); 

      sd = socket(AF_INET, SOCK_DGRAM, 0); 

      if(sd<0) { 
      printf("Failed to Open UDP socket"); 
      } 

      addr.sin_family = AF_INET; 
      addr.sin_addr.s_addr = htonl(INADDR_ANY); 
      addr.sin_port = htons(host_list[0]->port); 
      err = bind(sd,(struct sockaddr *) &addr,sizeof(addr)); 

      if(err < 0){ 
          printf("ERROR: Cant bind port"); 

      } 

          struct timeval tv; 
      while(1){ 
          FD_ZERO(&fds); 
          FD_SET(STDIN_FILENO,&fds); 
          FD_SET(sd,&fds); 
          tv.tv_sec = 1; 
          tv.tv_usec = 0; 
          fflush(stdout); 
          select(sd+1,&fds,NULL,NULL,&tv); 

          // If a UDP message arrives 
          if(FD_ISSET(sd,&fds)){ 
              n = recv(sd,udpbuf,sizeof(udpbuf),0); 
              unpack(udpbuf); 
              recompute_my_dv(); 
              fflush(stdout); 

          } 
          //If console data is entered. 
           if(FD_ISSET(STDIN_FILENO, &fds)){ 
              fgets(stdbuf,sizeof(stdbuf),stdin); 
              parse(stdbuf); 
              printf("server> "); 
              fflush(stdout); 
              FD_CLR(STDIN_FILENO,&fds); 


          } 

        } 



return 0; 
} 
+4

Haben Sie versucht zu überprüfen, was der'Auswahl'-Aufruf zurückgibt? –

+0

Sie wissen, dass 'STDIN' liniengepuffert ist? –

+0

@SergeyL - Die Zeilenpufferung erfolgt auf der Bibliotheks- oder Terminalebene, nicht auf der POSIX-Ebene. Es ist möglich, Stdin ungepuffert zu lesen. – Unsigned

Antwort

0

FD_ISSET nicht 1 (oder true) zurückgibt, wenn Sie auf das Socket-Puffer eine Nachricht haben, ist es true zurück, wenn der angegebene Dateideskriptor Teil des Datei Deskriptorenmenge ist. Das ist ein Problem.

Die nächste ist, dass Ihre Schleife beginnen sollte (die While-Schleife, die ist) sollte vor der Auswahl Anweisung und Schleife zurück zu diesem beginnen. Sie sollten den von der Auswahl zurückgegebenen Wert erfassen. Dies liegt daran, dass SELECT angibt, wie viele Bits in dem Puffer enthalten sind, den Sie in Argument 2 von select (Lesen, Schreiben oder Fehler) angegeben haben. Wenn Sie also "lese" als Puffer angeben, sollten Sie lesen, wie viele Bits von select zurückgegeben wurden.

Ich denke, das sind die 2 Hauptprobleme. Hoffe das hilft.