Assuming you want to continue using blocking sockets, you can use the SO_RCVTIMEO option:
SO_RCVTIMEO and SO_SNDTIMEO Specify the receiving or sending timeouts until reporting an error. The parameter is a struct timeval. If an input or out- put function blocks for this period of time, and data has been sent or received, the return value of that function will be the amount of data transferred; if no data has been transferred and the timeout has been reached then -1 is returned with errno set to EAGAIN or EWOULDBLOCK just as if the socket was specified to be nonblocking. If the timeout is set to zero (the default) then the operation will never timeout.
So, before you start getting:
struct timeval timeout = { timo_sec, timo_usec }; int r = setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)); assert(r == 0);
If you want to use non-blocking I / O, then you can use poll() , select() , epoll() , kqueue() or any appropriate event dispatch mechanism for your system. The reason you need to use non-blocking I / O is because you have to let the recv() system call return to notify you that there is no data in the socket input queue. An example of use is a little more in demand:
for (;;) { ssize_t bytes = recv(s, buf, sizeof(buf), MSG_DONTWAIT); if (bytes > 0) { continue; } if (bytes < 0) { if (errno == EWOULDBLOCK) { struct pollfd p = { s, POLLIN, 0 }; int r = poll(&p, 1, timo_msec); if (r == 1) continue; if (r == 0) { } } break; } break; }
source share