recv() windows socket takes infinite time - how to timeout?

ssk picture ssk · Jul 20, 2011 · Viewed 18k times · Source

I use file descriptors to find the readable sockets and go on to read. For some reasons, a socket that has no data on the wire, goes on to read and never returns. Is there a way I can come out of the receive after a timeout?

I am using winsock library..

Answer

Ben B picture Ben B · Jul 20, 2011

http://tangentsoft.net/wskfaq/newbie.html#timeout

2.15 - How can I change the timeout for a Winsock function?

Some of the blocking Winsock functions (e.g. connect()) have a timeout embedded into them. The theory behind this is that only the stack has all the information necessary to set a proper timeout. Yet, some people find that the value the stack uses is too long for their application; it can be a minute or longer.

You can adjust the send() and recv() timeouts with the SO_SNDTIMEO and SO_RCVTIMEO setsockopt() options. .

For other Winsock functions, the best solution is to avoid blocking sockets altogether. All of the non-blocking socket methods provide ways for you to build custom timeouts:

Non-blocking sockets with select() – The fifth parameter to the select() function is a timeout value.

Asynchronous sockets – Use the Windows API SetTimer().

Event objects – WSAWaitForMultipleEvents() has a timeout parameter.

Waitable Timers – Call CreateWaitableTimers() to make a waitable timer, which you can then pass to a function like WSAEventSelect() along with your sockets: if none of the sockets is signalled before the timer goes off, the blocking function will return anyway.

Note that with asynchronous and non-blocking sockets, you may be able to avoid handling timeouts altogether. Your program continues working even while Winsock is busy. So, you can leave it up to the user to cancel an operation that’s taking too long, or just let Winsock’s natural timeout expire rather than taking over this functionality in your code.