3

I have a client server connection where the client is sending data to the server.

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

The issue i only want to wait for a read to happen only for some seconds - in my code, if the client does not send anything, it gets stuck waiting for the server to read something.

How can I wait for a read to happen only some seconds please?

Gaurav Pathak
  • 1,065
  • 11
  • 28
CXB
  • 241
  • 5
  • 14
  • 4
    Possible duplicate of [How to implement a timeout in read function call?](http://stackoverflow.com/questions/2917881/how-to-implement-a-timeout-in-read-function-call) – rtur May 19 '17 at 11:12
  • @rtur I don't think that would work because this is a read in a IPC – CXB May 19 '17 at 11:50
  • 1
    @CXB How about [this](http://stackoverflow.com/questions/2876024/linux-is-there-a-read-or-recv-from-socket-with-timeout) – Gaurav Pathak May 19 '17 at 11:53
  • @CXB This works, read more about [nonblocking socket](https://www.scottklement.com/rpg/socktut/nonblocking.html) – Pravin May 19 '17 at 11:54
  • 3
    `n = read(sock, buffer);`??? `read()` takes 3 parameters. – Andrew Henle May 19 '17 at 11:57

3 Answers3

3

If your socket is non-blocking you can use the select function. If your socket is blocking you can set a read timeout using the setsockopt function. See this stackoverflow question for more details. Linux: is there a read or recv from socket with timeout?

Community
  • 1
  • 1
Stuart
  • 1,428
  • 11
  • 20
1

You can use select() api for this purpose. In this api u can mention the time in select api in seconds and microseconds.

Amol
  • 47
  • 1
  • 8
1

Basically the read call attempts to read so if you don't want to get stack on it you've to declare the sock variable as non-blocking or to use the select function with timeout (man select). In the first case you can't wait for some seconds but you can try to read k times and then go through. Here's the example for non-blocking 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);
            }
}

Here's the select solution:

/*
 * 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");
simo-r
  • 733
  • 1
  • 9
  • 13