2012-10-07 2 views
7

Ho un server che invia dati a un client ogni 5 secondi. Voglio che il client blocchi su read() finché il server non invia alcuni dati e poi li stampa. So che read() sta bloccando di default. Il mio problema è che il mio client non sta bloccando su read(). Questo è molto strano e questo non sembra essere un problema normale.read() non sta bloccando la programmazione socket

Il mio codice stampa "Niente è tornato" in un ciclo infinito. Sono su una macchina Linux, programmando in c. Il mio snippet di codice è sotto. Per favore consiglio

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

Avete controllato che la connessione sia aperta (cioè 'sockfd' è valido)? –

+16

Un valore di ritorno di 0 da 'read()' significa che l'altra estremità (il server) ha chiuso il socket. –

+0

@Ed Heal: Sì, è valido. Ho un assegno per quello. – Mathew

risposta

8

Ci possono essere diverse cause e diversi eccezioni sono possibili in luogo diverso:

  1. presa di controllo in cui si crea:

    sockfd=socket(AF_INET,SOCK_STREAM,0); 
    if (sockfd==-1) { 
        perror("Create socket"); 
    } 
    
  2. voi e anche attivare la modalità di blocco in modo esplicito prima usalo:

    oppure è possibile utilizzare setsockopt come di seguito:

    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. Controllare il funzionamento Leggi di chiamata (Motivo di bug)

    n = read(sockfd, recvline, MAXLINE); 
    if(n < 0){ 
        perror("Read Error:"); 
    } 
    
  4. anche controllo codice server:

    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. Un'altra cosa interessante, Cercate di capire:

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

+1

Grazie per l'elaborata risposta, amico. Proverò a correggere i bug anche sul server e vedere se sta inviando qualcosa di strano. – Mathew

+0

La modalità di blocco è l'impostazione predefinita: non è necessario impostarla in modo esplicito. Il codice in (2) che chiama setsockopt() con argomenti di & 0 e sizeof (sockfd) è completo senza senso e non verrà compilato. Downvote. – EJP

+0

@EJP: so che la modalità predefinita sta bloccando. Volevo solo dire come impostare in modo esplicito la modalità di blocco (o ripristinare la modalità di blocco). PER ERRORE COMPILE: ho corretto il codice dell'opzione setsock() e la mia richiesta: per favore verifica e se è ancora un errore si prega di correggere in modo che si possa ottenere l'aiuto corretto ... grazie EJP! –

1

Qual è il valore di MAXLINE?

Se il valore è 0, restituirà anche 0. Altrimenti, come menziona Grijesh Chauhan, impostalo esplicitamente sul blocco.

Oppure, si può anche considerare l'utilizzo di recv() in cui è possibile specificare il blocco e il non blocco. Ha l'opzione, MSG_WAITALL, dove bloccherà fino all'arrivo di tutti i byte.

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

Buona idea !! Proverò recv(). Potrebbe fare il trucco. – Mathew

3

Cosa Greg Hewgill già scritto come commento: Un EOF (vale a dire, un arresto esplicita della scrittura, sia essa tramite close() o via shutdown()) sarà comunicata al lato ricevente avendo recv() ritorno 0. Quindi se ottieni 0, sai che non ci saranno dati e puoi interrompere il ciclo di lettura.

Se trovassi non bloccante abilitato e non ci sono dati, si otterrà -1 e errno sarà impostato EAGAIN o EWOULDBLOCK.

+0

Non penso che questo sia il problema. Il server è in un ciclo infinito, continua a inviare dati al client ogni 5 secondi. Il server, bydesign, non dovrebbe spegnersi affatto. – Mathew

+0

Non il server, ma il "client socket" del server potrebbe ... – glglgl