2017-05-19 2 views
0

Ich habe eine Client-Server-Verbindung, wo der Client Daten an den Server sendet.Einstellung Socket-Timeout für die Empfangsfunktion

while (1) { 

    bzero(buffer, 256); 
    sleep(1); 

    n = read(sock, buffer); 
    if(n < 0) error("ERROR reading from socket"); 
    c = message[0]; 

    //do something 

}//close while loop 

Das Problem ich mag nur warten, bis eine Lese nur für einige Sekunden passieren - in meinem Code, wenn der Kunde hat nichts senden, es wird für den Server stecken wartet etwas zu lesen.

Wie kann ich darauf warten, dass ein Lesevorgang nur für einige Sekunden erfolgt?

+3

Mögliches Duplikat von [Wie ein Timeout in Lesefunktionsaufruf implementieren?] (Http://stackoverflow.com/questions/2917881/how-to-implement-a-timeout-in-read-function-call) – rtur

+0

@rtur Ich denke nicht, dass das funktionieren würde, weil dies in einem IPC gelesen wird – CXB

+1

@ CXB Wie wäre es mit [dies] (http://stackoverflow.com/questions/2876024/linux-is-there-a-read- or-recv-from-socket-with-timeout) – Gaurav

Antwort

1

Sie können select() api für diesen Zweck verwenden. In diesem Fall kann die Zeit in ausgewählten api in Sekunden und Mikrosekunden angegeben werden.

+0

Ich habe versucht mit Select, aber jetzt gibt es nichts aus – CXB

+0

Können Sie mir die Syntax Ihrer Select-API zeigen. – Amol

0

Grundsätzlich sind die read Anrufversuche so zu lesen, wenn Sie Stapel nicht erhalten möchten Sie darauf, Sie haben die sock Variable als nicht-blockierend zu erklären oder die select Funktion mit Timeout zu verwenden (man select). Im ersten Fall können Sie nicht einige Sekunden warten, aber Sie können versuchen, k mal zu lesen und dann durchzugehen. Hier ist das Beispiel für nicht-blockierenden Socket:

/* 
* Non-blocking socket solution 
* just put the read in a for-loop 
* if you want to read k times 
*/ 


#include <errno.h> 
#include <fcntl.h> 
#include <unistd.h> 

int r1; 
/*Setting the socket as non-blocking*/ 
int flags = fcntl(sock, F_GETFL, 0); 
fcntl(sock, F_SETFL, flags | O_NONBLOCK); 
errno = 0; /*If the read fails it sets errno*/ 
if((r1=read(sock,buf_in,N))== -1) { /*If the read returns an error*/ 
    if(errno != EAGAIN && errno != EWOULDBLOCK){ /*If the error is not caused by the non-blocking socket*/ 
       perror("Error in read\n"); 
       exit(EXIT_FAILURE); 
      } 
} 

Hier ist die Lösung auswählen:

/* 
* Select solution. 
* This is not a complete solution but 
* it's almost everything you've to do 
*/ 


#include <errno.h> 
#include <fcntl.h> 
#include <unistd.h> 
#include <sys/select.h> 

#define SVC(r,c,e) \ 
    errno = 0; \ 
    if((r=c)==-1) { perror(e);exit(errno); } 

int r = 0; 
int fd_skt; 
fd_set rdset; 
fd_set set; 
struct timeval tv; /*Timer structure*/ 
int fd_num_max = 0; /*Maximum opened file descriptor*/ 
if(fd_skt > fd_num_max) fd_num_max = fd_skt; 
FD_ZERO(set); 
FD_SET(fd_skt,set); /*fd_skt is where you're waiting for new connection request*/ 
/*Setting the timer*/ 
tv.tv_sec = 0; 
tv.tv_usec = 200*1000; 
rdset = set; 
SVC(r,select((fd_num_max+1),(&rdset),NULL,NULL,&tv),"Unable to select\n"); 
Verwandte Themen