2012-10-07 8 views
7

Ich habe einen Server, der alle 5 Sekunden Daten an einen Client sendet. Ich möchte, dass der Client bei read() blockiert, bis der Server einige Daten sendet und dann druckt. Ich weiß, dass read() standardmäßig blockiert. Mein Problem ist, dass mein Client nicht auf read() blockiert. Das ist sehr merkwürdig und das scheint kein normales Problem zu sein.lesen() blockiert nicht in Socket-Programmierung

Mein Code druckt "Nichts kam zurück" in einer Endlosschleife. Ich bin auf einer Linux-Maschine, Programmierung in c. Mein Codeausschnitt ist unten. Bitte um Rat.

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

Haben Sie überprüft, dass die Verbindung offen ist (d. H. "Sockfd" ist gültig)? –

+16

Ein Rückgabewert von 0 von 'read()' bedeutet, dass das andere Ende (der Server) den Socket geschlossen hat. –

+0

@Ed Heal: Ja, es ist gültig. Ich habe einen Scheck dafür. – Mathew

Antwort

8

Es kann mehrere Ursachen und mehrere Ausnahmen an anderer Stelle möglich sind:

  1. Kontroll Steckdose, wo Sie erstellen:

    sockfd=socket(AF_INET,SOCK_STREAM,0); 
    if (sockfd==-1) { 
        perror("Create socket"); 
    } 
    
  2. Sie und ermöglichen auch Modus blockiert ausdrücklich vor Verwenden Sie es:

    oder können Sie setsockopt verwenden, wie unten:

    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. Prüflesevorgang Funktionsaufruf (Ursache des Fehlers)

    n = read(sockfd, recvline, MAXLINE); 
    if(n < 0){ 
        perror("Read Error:"); 
    } 
    
  4. Auch Check-Server-Code:

    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. Eine weitere interessante Sache, Versuchen Sie zu verstehen:

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

+1

Danke für die ausführliche Antwort, Mann. Ich werde versuchen, den Server auch zu reparieren, um zu sehen, ob er etwas seltsames Zeug sendet. – Mathew

+0

Blockiermodus ist der Standardwert: Sie müssen ihn nicht explizit festlegen. Der Code in (2), der setsockopt() mit Argumenten von & 0 und sizeof (sockfd) aufruft, ist kompletter Unsinn und wird nicht kompiliert. Downvote. – EJP

+0

@EJP: Ich weiß, Standardmodus blockiert. Ich wollte nur sagen, wie man den Sperrmodus explizit einstellt (oder auf den Sperrmodus zurücksetzt). COMPILE FEHLER: Ich korrigiere den Code der setsock() Option und meine Anfrage an Sie: Bitte überprüfen Sie und wenn es immer noch falsch ist Bitte korrigieren Sie, so dass man richtige Hilfe bekommen kann .. Dank EJP! –

1

Was ist der Wert von MaxLine?

Wenn der Wert 0 ist, wird auch 0 zurückgegeben. Andernfalls, wie Grijesh Chauhan erwähnt, setzen Sie es explizit auf Blockieren.

Oder Sie können auch recv() verwenden, bei dem blockierend und nicht blockierend angegeben werden kann. Es hat die Option MSG_WAITALL, wo es blockiert wird, bis alle Bytes angekommen sind.

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

Gute Idee !! Ich werde versuchen, recv(). Es könnte den Trick machen. – Mathew

3

Was Greg Hewgill bereits als Kommentar geschrieben: Ein EOF (das heißt, ein expliziter Stopp des Schreibens, sei es über close() oder über shutdown()) wird 0. Also, indem recv() Rückkehr zur Empfangsseite übertragen werden Wenn Sie 0 erhalten, wissen Sie, dass keine Daten vorhanden sind und Sie die Leseschleife beenden können.

Wenn Sie nicht blockierend aktiviert hatte und es gibt keine Daten, werden Sie -1 erhalten und errno wird EAGAIN oder EWOULDBLOCK eingestellt werden.

+0

Ich denke nicht, dass das das Problem ist. Der Server befindet sich in einer Endlosschleife und sendet alle 5 Sekunden Daten an den Client. Der Server, bydesign, soll gar nicht herunterfahren. – Mathew

+0

Nicht der Server, aber der "Client-Socket" des Servers ... – glglgl

Verwandte Themen