2017-05-19 5 views
0

J'ai une connexion au serveur client où le client envoie des données au serveur.Définition de la temporisation du socket pour la fonction de réception

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 

La question que je veux seulement attendre une lecture pour se produire que pendant quelques secondes - dans mon code, si le client n'envoie rien, il est bloqué en attente pour le serveur de lire quelque chose.

Comment puis-je attendre qu'une lecture ne se produise que quelques secondes, s'il vous plaît?

+3

Duplication possible de [Comment implémenter un timeout dans un appel de fonction de lecture?] (Http://stackoverflow.com/questions/2917881/how-to-implement-a-timeout-in-read-function-call) – rtur

+0

@rtur Je ne pense pas que cela fonctionnerait parce que c'est une lecture dans un IPC – CXB

+1

@CXB Que diriez-vous de [this] (http://stackoverflow.com/questions/2876024/linux-is-there-a-read- ou-recv-from-socket-with-timeout) – Gaurav

Répondre

1

Vous pouvez utiliser select() api à cette fin. Dans cette api, vous pouvez mentionner l'heure de sélectionner api en secondes et en microsecondes.

+0

J'ai essayé d'utiliser select mais maintenant il ne sort rien – CXB

+0

Pouvez-vous me montrer la syntaxe de votre api de sélection. – Amol

0

Fondamentalement, les tentatives d'appel read à lire donc si vous ne voulez pas obtenir pile dessus, vous avez à déclarer la variable sock comme non-blocage ou d'utiliser la fonction select avec délai d'attente (man select). Dans le premier cas, vous ne pouvez pas attendre quelques secondes, mais vous pouvez essayer de lire k fois et ensuite passer. Voici l'exemple pour socket non bloquant:

/* 
* 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); 
      } 
} 

est ici la solution select:

/* 
* 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");