2012-05-19 14 views
5
#include <stdio.h> 
#include <unistd.h> 
#include <sys/time.h> 
#include <sys/types.h> 

int main() 
{ 
char   name[20]; 
fd_set   input_set; 
struct timeval timeout; 
int    ready_for_reading = 0; 
int    read_bytes = 0; 

/* Empty the FD Set */ 
FD_ZERO(&input_set); 
/* Listen to the input descriptor */ 
FD_SET(0, &input_set); 

/* Waiting for some seconds */ 
timeout.tv_sec = 10; // 10 seconds 
timeout.tv_usec = 0; // 0 milliseconds 

/* Invitation for the user to write something */ 
printf("Enter Username: (in 15 seconds)\n"); 
printf("Time start now!!!\n"); 

/* Listening for input stream for any activity */ 
ready_for_reading = select(1, &input_set, NULL, NULL, &timeout); 
/* Here, first parameter is value of the socket descriptor + 1 (STDIN descriptor is 0, so 
* 0 +1 = 1) 
* in the set, second is our FD set for reading, 
* third is the FD set in which any write activity needs to updated, which is not required 
* in this case. Fourth is timeout 
*/ 

if (ready_for_reading == -1) { 
    /* Some error has occured in input */ 
    printf("Unable to read your input\n"); 
    return -1; 
} else { 
    if (ready_for_reading) { 
     read_bytes = read(0, name, 19); 
     printf("Read, %d bytes from input : %s \n", read_bytes, name); 
    } else { 
     printf(" 10 Seconds are over - no data input \n"); 
    } 
} 

return 0; 

}Cómo bucle select() para sondear el infinito datos

Cómo hacer lo mismo, pero no sólo una vez, pero en bucle infinito que se rompe después de encontrarse con 'Salir' de cadena (por ejemplo) . De todos modos lo intenté, fallé. Entonces, si no se han ingresado datos después de 10 segundos, el programa simplemente imprime "10 segundos han terminado, no hay datos ingresados" y luego vuelve a esperar. Lo mismo después de la entrada: simplemente comienza de nuevo y se comporta igual siempre en bucle infinito.
Ya estoy un poco desesperado, por favor, ayuda.
Gracias.

+3

Pon todo en un bucle 'while (! Strcmp (name," quit "))' o algo así? :-) –

+0

"Aquí, el primer parámetro es el número de FD en el conjunto" ** no **. Debe ser el número más alto de FD más uno. Por favor, vuelva a verificar la página de manual. – Mat

+1

El ejemplo en la parte inferior de http://linux.die.net/man/2/select_tut es exactamente lo que desea. –

Respuesta

4

Realmente no veo el problema aquí. Básicamente ponga todo lo que desea en el ciclo y déjelo funcionar. ¿Has intentado esto?

int main() 
{ 
    /* Declarations and stuff */ 
    /* ... */ 

    /* The loop */ 
    int break_condition = 0; 
    while (!break_condition) 
    { 
     /* Selection */ 
     FD_ZERO(&input_set); /* Empty the FD Set */ 
     FD_SET(0, &input_set); /* Listen to the input descriptor */ 
     ready_for_reading = select(1, &input_set, NULL, NULL, &timeout); 

     /* Selection handling */ 
     if (ready_for_reading) 
     { 
      /* Do something clever with the input */ 
     } 
     else 
     { 
      /* Handle the error */ 
     } 

     /* Test the breaking condition */ 
     break_condition = some_calculation(); 
    } 
    return 0; 
} 

Tenga en cuenta que usted tiene que volver a activar siempre tiene la selección dentro del bucle de manera que es capaz de responder de nuevo en la siguiente iteración.

+0

Muchas gracias a todos. Resuelto al fin! :))) El problema fue que inicialicé los argumentos de selección solo una vez, y luego los utilicé varias veces, mientras que debería inicializarlos cada vez que uso select. De verdad muchas gracias. !!!! Saludos – azrahel

0

La función de selección() puede bloquearse indefinidamente estableciendo tiempo de espera en NULO. Ver select (2) página del manual:

tiempo de espera es un límite superior en la cantidad de tiempo transcurrido antes de seleccionar retornos(). Si ambos campos de timeval stucture son cero, entonces seleccione() regresa inmediatamente. (Esto es útil para el sondeo). Si timeout es NULL (sin tiempo de espera), seleccione() puede bloquear indefinidamente.

Así que lo que quiere decir:

... 
ready_for_reading = select(1, &input_set, NULL, NULL, NULL); 
...