2012-10-07 46 views
7

Tengo un servidor que envía datos a un cliente cada 5 segundos. Quiero que el cliente bloquee en read() hasta que el servidor envíe algunos datos y luego los imprima. Sé que read() está bloqueando por defecto. Mi problema es que mi cliente no está bloqueando en read(). Esto es muy extraño y esto no parece ser un problema normal.read() no está bloqueando en la programación de socket

Mi código imprime "Nada regresó" en un ciclo infinito. Estoy en una máquina Linux, programando en c. Mi fragmento de código está a continuación. Por favor aconséjame.

while(1) 
{ 
    n = read(sockfd, recvline, MAXLINE); 
    if (n > 0) 
    { 
     recvline[n] = 0;  
     if (fputs(recvline, stdout) == EOF) 
      printf("fputs error"); 
    } 
    else if(n == 0) 
     printf("Nothing came back"); 
    else if (n < 0) 
     printf("read error"); 
} 
return; 
+3

¿Ha comprobado que la conexión está abierta (es decir, 'sockfd' es válido)? –

+16

Un valor de retorno de 0 desde 'leer()' significa que el otro extremo (el servidor) cerró el socket. –

+0

@Ed Heal: Sí, es válido. Tengo un cheque por eso. – Mathew

Respuesta

8

Puede haber varias excepciones de causa y varios son posibles en un lugar diferente:

  1. zócalo de verificación donde se crea:

    sockfd=socket(AF_INET,SOCK_STREAM,0); 
    if (sockfd==-1) { 
        perror("Create socket"); 
    } 
    
  2. y para activar el modo de bloqueo de forma explícita antes úselo:

    o puede utilizar setsockopt de la siguiente manera:

    struct timeval t;  
    t.tv_sec = 0; 
    tv_usec = 0; 
    setsockopt(
         sockfd,  // Socket descriptor 
         SOL_SOCKET, // To manipulate options at the sockets API level 
         SO_RCVTIMEO,// Specify the receiving or sending timeouts 
         const void *(&t), // option values 
         sizeof(t) 
    ); 
    
  3. Comprobar la función Leer llamada (Razón del fallo)

    n = read(sockfd, recvline, MAXLINE); 
    if(n < 0){ 
        perror("Read Error:"); 
    } 
    
  4. también código de servidor de comprobación:

    1. May your server send some blank(non-printable, null, enter) charter(s). And your are unaware of this. Bug you server code too.

    2. Or your server terminated before your client can read.

  5. Una cosa más interesante, trata de entender:

    When you call N write() at server its not necessary there should be N read() call at other side.

+1

Gracias por la elaborada respuesta, hombre. Intentaré corregir también el servidor y veré si está enviando algunas cosas extrañas. – Mathew

+0

El modo de bloqueo es el predeterminado: no tiene que establecerlo explícitamente. El código en (2) que llama a setsockopt() con argumentos de & 0 y sizeof (sockfd) es una tontería completa y no se compilará. Voto abajo. – EJP

+0

@EJP: sé que el modo predeterminado es el bloqueo. Solo quería decir cómo configurar explícitamente el modo de bloqueo (o restablecer al modo de bloqueo). PARA EL ERROR DE COMPILACIÓN: Corregí el código de la opción setsock() y Mi SOLICITUD: por favor verifique y si todavía está mal, rectifique para que pueda obtener la ayuda correcta. ¡Gracias EJP! –

1

¿Cuál es el valor de MAXLINE?

Si el valor es 0, también devolverá 0. De lo contrario, como menciona Grijesh Chauhan, configúrelo explícitamente como bloqueador.

O, también puede considerar el uso de recv() donde se puede especificar bloqueo y no bloqueo. Tiene la opción, MSG_WAITALL, donde se bloqueará hasta que lleguen todos los bytes.

n = recv(sockfd, recvline, MAXLINE, MSG_WAITALL); 
+0

¡¡Buena idea !! Voy a intentar recv(). Podría hacer el truco. – Mathew

3

Lo Greg Hewgill ya se escribió como un comentario: un EOF (es decir, una parada explícita de la escritura, ya sea a través de close() oa través de shutdown()) se comunicará a la parte receptora por tener recv() retorno 0. Entonces, si obtienes 0, sabes que no habrá datos y puedes terminar el ciclo de lectura.

Si había permitido no bloqueante y no hay datos, obtendrá -1 y errno se establecerá en EAGAIN o EWOULDBLOCK.

+0

No creo que este sea el problema. El servidor está en un bucle infinito, sigue enviando datos al cliente cada 5 segundos. El servidor, bydesign, no debe apagarse en absoluto. – Mathew

+0

No es el servidor, pero el "socket del cliente" del servidor tal vez ... – glglgl

Cuestiones relacionadas