2016-04-27 10 views
0

Ich habe ein paar Tipps, wie es geht, aber ich verstehe nicht, wie Sie Setsockopt verwenden. Ich habe eine unendliche While-Schleife mit recv anrufen, ich möchte Timeout und close(cli_socket), wenn Client nicht in 5 Sekunden etwas sendet.Einstellung Timeout für Socket recv TCP

Wenn Client sendet nur einen Teil der gesamten erwarteten Nachricht Ich möchte Timer zurücksetzen und geben Sie ihm weitere 5 Sekunden.

currentry Ich habe dies:

while((cut = buffer.find("\r\n")) == -1) 
     { 
      struct timeval tv; 
      tv.tv_sec = 5; 
      setsockopt(cli_socket, SOL_SOCKET, SO_RCVTIMEO,(struct timeval *)&tv,sizeof(struct timeval)); 
      recv(cli_socket, tmpBuffer, 100, 0); 
      buffer += tmpBuffer; 
      memset(tmpBuffer, 0, 100); 
     } 
+0

Sie 'setsockopt' Anruf scheint in Ordnung zu mir, und es funktioniert für mich. Welches Verhalten siehst du und wie unterscheidet es sich von dem, was du erwartest? Ich bemerke, dass Sie den Rückgabewert von 'recv()' nicht überprüfen, und das lässt mich fragen, was Sie erwarten würden, wenn es abläuft. – Dolda2000

+0

Ich möchte die Verbindung schließen, wenn es Timeouts – lllook

Antwort

3

Sie sollten die Rückkehr von recv und break Ihre Schleife testen, ob es EAGAIN oder EWOULDBLOCK:

EAGAIN oder EWOULDBLOCK
Die Buchse ist nicht blockierend markiert und die Empfangsoperation würde blockieren, oder es wurde ein Empfangszeitlimit gesetzt und die Zeit abgelaufen, bevor die Daten empfangen wurden

struct timeval tv = {5, 0}; 
setsockopt(cli_socket, SOL_SOCKET, SO_RCVTIMEO, (struct timeval *)&tv, sizeof(struct timeval)); 

while((cut = buffer.find("\r\n")) == -1) 
{ 
    int numBytes = recv(cli_socket, tmpBuffer, 100, 0)); 

    /// Edit: recv does not return EAGAIN else, it return -1 on error. 
    /// and in case of timeout, errno is set to EAGAIN or EWOULDBLOCK 

    if (numBytes <= 0) 
    { 
     // nothing received from client in last 5 seconds 
     break; 
    } 

    buffer.append(tmpBuffer, numBytes); 
} 

Sie können auch select Funktion benutzen, die nicht so kompliziert zu bedienen ist:

while((cut = buffer.find("\r\n")) == -1) 
{ 
    timeval timeout = { 5, 0 }; 
    fd_set in_set; 

    FD_ZERO(&in_set); 
    FD_SET(cli_socket, &in_set); 

    // select the set 
    int cnt = select(cli_socket + 1, &in_set, NULL, NULL, &timeout); 

    if (FD_ISSET(cli_socket, &in_set)) 
    { 
     int numBytes = recv(cli_socket, tmpBuffer, 100, 0)); 
     if (numBytes <= 0) 
     { 
      // nothing received from client 
      break; 
     } 

     buffer.append(tmpBuffer, numBytes); 
    } 
    else 
    { 
     // nothing received from client in last 5 seconds 
     break;  
    } 
} 
+0

Umfrage ist viel besser als wählen. – SergeyA

+0

Danke! Ich weiß über Select() -Methode, die ich erfolgreich verwendet habe, war meine Absicht zu lernen, wie man Setsockopt für Timeouts verwendet – lllook

+0

Noch eine Frage, hat Code oben wirklich zurückgesetzt Timeout, nachdem ich zumindest etwas erhalten? – lllook