2013-04-22 12 views
5

Sto scrivendo un programma che riceve messaggi UDP e riceve input dagli utenti, tuttavia il mio STDIN sta ancora bloccando con select. Quando FD_CLR lo stdin fd prima seleziona il programma funziona bene, indicando che il socket stdin è sempre pronto ad avere i dati letti da esso. Ho provato a introdurre una tv in tempo reale per crearla, ma non sembra funzionare. Dovrei chiudere il socket da qualche parte o chiamare FD_CLR dove non lo sono? Il risultato finale dovrebbe essere un STDIN non bloccante ma al momento si blocca. Thank YouSelezionare() il blocco su stdin, non scade il tempo

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

Avete provato a verificare cosa restituisce la chiamata 'select'? –

+0

Sapete che 'STDIN' è in modalità line buffer? –

+0

@SergeyL - Il buffering di riga viene eseguito a livello di libreria o di terminale, non verso il livello POSIX. È possibile leggere lo stdin in modo non bufferizzato. – Unsigned

risposta

0

FD_ISSET non restituisce 1 (o vero) se si dispone di un messaggio sul buffer che di socket, che restituisce true se il dato descrittore di file è parte del set di descrittore di file. Questo è un problema

Il prossimo è che il ciclo dovrebbe iniziare (il ciclo while) dovrebbe iniziare prima della selezione e tornare a quello. È necessario acquisire il valore restituito dalla selezione. Questo perché select restituisce quanti bit ci sono nel buffer specificato nell'argomento 2 di select (read, write, o error). Quindi se hai specificato read come buffer, vorrai leggere come mai molti bit sono stati restituiti da select.

Penso che questi siano i 2 problemi principali. Spero che questo ti aiuti.