Discussion:
Can't change socket receive timeout ??!!
(too old to reply)
Chris Cooper
2003-07-30 23:28:33 UTC
Permalink
I'm using Windows sockets to connect to a web site and download a file via
HTTP. All works beautifully until I try to download a file that is large
(4M). The socket times out after 30 seconds, even though all of the data is
still flowing.

I tried setting the SO_RCVTIMEO and SO_SNDTIMEO options to large numbers,
and it seemed to work (setsockopt returned 0 and getsockopt returned the
value I had just passed it) but the socket still closes itself after 30
seconds.

Is there another timeout value somewhere I need to set?

Thanks!
Chris
Sreeram
2003-07-31 05:54:34 UTC
Permalink
Are you using WinSock 2? SO_SNDTIMEO and SO_RCVTIMEO options are
available in Winsock 2.

or you can make it a as a non-blocking socket and do the timeout
calculation manually instead of using this SetSockOpt function.

Sreeram
Post by Chris Cooper
I'm using Windows sockets to connect to a web site and download a file via
HTTP. All works beautifully until I try to download a file that is large
(4M). The socket times out after 30 seconds, even though all of the data is
still flowing.
I tried setting the SO_RCVTIMEO and SO_SNDTIMEO options to large numbers,
and it seemed to work (setsockopt returned 0 and getsockopt returned the
value I had just passed it) but the socket still closes itself after 30
seconds.
Is there another timeout value somewhere I need to set?
Thanks!
Chris
Chris Cooper
2003-07-31 09:47:12 UTC
Permalink
Here's what I'm doing. I call select() until there is data available for
reading, and then call recv() to get a small chunk of data (max 16k). If
recv() didn't return zero (which would indicate that the socket is closed) I
go back and call select() again. I can go through this loop hundreds of
times without problems, but if the total time the socket is receiving data
is more than 30 seconds, recv() returns zero even though there is more data
to be read.

What's strange, is that it's not that any single call is taking more than 30
seconds, it's if the total duration of the receive takes more than 30
seconds.

I'm assuming that by calling select() first, it's effectively a non-blocking
socket?
Post by Sreeram
Are you using WinSock 2? SO_SNDTIMEO and SO_RCVTIMEO options are
available in Winsock 2.
or you can make it a as a non-blocking socket and do the timeout
calculation manually instead of using this SetSockOpt function.
Sreeram
Post by Chris Cooper
I'm using Windows sockets to connect to a web site and download a file via
HTTP. All works beautifully until I try to download a file that is large
(4M). The socket times out after 30 seconds, even though all of the data is
still flowing.
I tried setting the SO_RCVTIMEO and SO_SNDTIMEO options to large numbers,
and it seemed to work (setsockopt returned 0 and getsockopt returned the
value I had just passed it) but the socket still closes itself after 30
seconds.
Is there another timeout value somewhere I need to set?
Thanks!
Chris
Sreeram
2003-07-31 11:38:12 UTC
Permalink
To make a socket as non-blocking socket:

u_long cmd_option = 1; //Non-blocking socket.

//Set socket in non-blocking mode
ioctlsocket(mastersd, FIONBIO, &cmd_option);

// rest of your code...

Then socket will be in non-blocking mode and the recv will return
immediatly by reading the available data in the socket at that
particular time.

I think you are calling select with a timeout value. If you are passing
NULL then it will be a blocking socket.

Also please check this: http://tangentsoft.net/wskfaq/newbie.html

This is from Internet I will paste the relevant portion here.

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.

Under Winsock 2, you can set the SO_SNDTIMEO and SO_RCVTIMEO options
with setsockopt() to change the timeouts for send() and recv().

Unfortunately, the Winsock spec does not document a way to change many
other timeout values, and the above advice doesn't apply to Winsock 1.1.

The solution is to avoid blocking sockets altogether. All of the
non-blocking socket methods lend themselves to 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 These are a new feature in Windows 98 and NT 4.0
SP3 and higher. A waitable timer is an object like a semaphore, except
that the OS signals it at a future time that you specify. You create
them with the Win32 function CreateWaitableTimers(). So, you could wait
on a 5-second timer as well as your event objects; if nothing happens on
the sockets within 5 seconds, Windows will signal the timer, thus
breaking you out of the WaitForMultipleObjects() call.

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.

Cheers
Sreeram
Post by Chris Cooper
Here's what I'm doing. I call select() until there is data available for
reading, and then call recv() to get a small chunk of data (max 16k). If
recv() didn't return zero (which would indicate that the socket is closed) I
go back and call select() again. I can go through this loop hundreds of
times without problems, but if the total time the socket is receiving data
is more than 30 seconds, recv() returns zero even though there is more data
to be read.
What's strange, is that it's not that any single call is taking more than 30
seconds, it's if the total duration of the receive takes more than 30
seconds.
I'm assuming that by calling select() first, it's effectively a non-blocking
socket?
Post by Sreeram
Are you using WinSock 2? SO_SNDTIMEO and SO_RCVTIMEO options are
available in Winsock 2.
or you can make it a as a non-blocking socket and do the timeout
calculation manually instead of using this SetSockOpt function.
Sreeram
Post by Chris Cooper
I'm using Windows sockets to connect to a web site and download a file
via
Post by Sreeram
Post by Chris Cooper
HTTP. All works beautifully until I try to download a file that is
large
Post by Sreeram
Post by Chris Cooper
(4M). The socket times out after 30 seconds, even though all of the
data is
Post by Sreeram
Post by Chris Cooper
still flowing.
I tried setting the SO_RCVTIMEO and SO_SNDTIMEO options to large
numbers,
Post by Sreeram
Post by Chris Cooper
and it seemed to work (setsockopt returned 0 and getsockopt returned the
value I had just passed it) but the socket still closes itself after 30
seconds.
Is there another timeout value somewhere I need to set?
Thanks!
Chris
Chris Cooper
2003-07-31 18:08:48 UTC
Permalink
I changed my code to call recv() repeatedly as you suggested, which seems
like a good idea, and unfortunately the packet is still timing out after 30
seconds.
Post by Chris Cooper
Here's what I'm doing. I call select() until there is data available for
reading, and then call recv() to get a small chunk of data (max 16k).
If
Post by Chris Cooper
recv() didn't return zero (which would indicate that the socket is closed) I
go back and call select() again.
When select() tells you data is available you should loop on a
non-blocking
recv() until it returns an error set to EWOULDBLOCK, then call select()
again.
Otherwise your receive buffers may be filling up, stalling the connection,
and
causing the sender to close the connection.
--
Phil Frisbie, Jr.
Hawk Software
http://www.hawksoft.com
Phil Frisbie, Jr.
2003-07-31 21:09:50 UTC
Permalink
Post by Chris Cooper
I changed my code to call recv() repeatedly as you suggested, which seems
like a good idea, and unfortunately the packet is still timing out after 30
seconds.
You have something buggy in your code... Can you distill your code into a single
function or console app and post it?
--
Phil Frisbie, Jr.
Hawk Software
http://www.hawksoft.com
Continue reading on narkive:
Loading...