2012-10-07 8 views
7

Mam serwer, który wysyła dane do klienta co 5 sekund. Chcę, aby klient blokował podczas odczytu(), dopóki serwer nie wyśle ​​niektórych danych, a następnie wydrukuje. Wiem, że read() jest domyślnie blokowany. Mój problem polega na tym, że mój klient nie blokuje odczytu(). Jest to bardzo dziwne i nie wydaje się to normalnym problemem.read() nie blokuje w programowaniu gniazd

Mój kod drukuje "Nic nie wróciło" w nieskończonej pętli. Jestem na maszynie Linux, programowanie w c. Mój fragment kodu znajduje się poniżej. Proszę o poradę.

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

Czy sprawdziłeś, czy połączenie jest otwarte (np. "Sockfd" jest ważne)? –

+16

Zwracana wartość 0 z 'read()' oznacza, że ​​drugi koniec (serwer) zamknął gniazdo. –

+0

@Ed Heal: Tak, jest poprawna. Mam czek na to. – Mathew

Odpowiedz

8

Może być kilka przyczyna i kilka wyjątki są możliwe w innym miejscu:

  1. sprawdzić gniazdo gdzie tworzyć:

    sockfd=socket(AF_INET,SOCK_STREAM,0); 
    if (sockfd==-1) { 
        perror("Create socket"); 
    } 
    
  2. Ty i również włączyć tryb blokowania jawnie przed użyj go:

    lub użyć setsockopt jak poniżej:

    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. wyboru Odczyt funkcji połączenia (przyczyna błędu)

    n = read(sockfd, recvline, MAXLINE); 
    if(n < 0){ 
        perror("Read Error:"); 
    } 
    
  4. także sprawdzić kod serwera:

    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. Jeszcze jedna interesująca rzecz, spróbuj zrozumieć:

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

+1

Dzięki za wyszukaną odpowiedź, stary. Spróbuję naprawić błąd serwera i sprawdzić, czy wysyła on jakieś dziwne rzeczy. – Mathew

+0

Tryb blokowania jest domyślny: nie trzeba go ustawiać jawnie. Kod w (2) wywołujący setsockopt() z argumentami & 0 i sizeof (sockfd) jest kompletnym nonsensem i nie będzie się kompilował. Downvote. – EJP

+0

@EJP: Wiem, że tryb domyślny jest blokowany. Chciałem tylko powiedzieć, jak jawnie ustawić tryb blokowania (lub zresetować do trybu blokowania). DLA BŁĘDU KOMPILACYJNEGO: Poprawiłem kod opcji setsock() i MOJE ZAPYTANIE: zweryfikuj i jeśli nadal jest źle Proszę napraw, aby uzyskać poprawną pomoc. Dzięki EJP! –

1

Jaka jest wartość MaXLine?

Jeśli wartość wynosi 0, to zwróci również 0. W przeciwnym razie, jak wspomina Grijesh Chauhan, ustaw to explicite na blokowanie.

Można też rozważyć użycie funkcji recv(), w której można określić blokowanie i nieblokowanie. Ma opcję, MSG_WAITALL, gdzie będzie blokować, aż wszystkie bajty nadejdą.

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

Dobry pomysł !! I shal try recv(). To może załatwić sprawę. – Mathew

3

Co Greg Hewgill już napisałem jako komentarz: EOF (czyli wyraźne zatrzymanie piśmie, czy to poprzez close() lub poprzez shutdown()) zostaną przekazane stronie odbiorczej poprzez recv() zwrot 0. So jeśli otrzymasz 0, wiesz, że nie będzie żadnych danych i możesz przerwać pętlę czytania.

Jeśli miał non-blokowanie włączone i nie ma żadnych danych, otrzymasz -1 i errno zostanie ustawiona na EAGAIN lub EWOULDBLOCK.

+0

Nie sądzę, że to jest problem. Serwer znajduje się w nieskończonej pętli, wysyła dane do klienta co 5 sekund. Serwer, bydesign, nie powinien w ogóle się wyłączać. – Mathew

+0

Nie serwer, ale "gniazdo klienta" serwera może ... – glglgl

Powiązane problemy