Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Send and Receive timeouts

1 view
Skip to first unread message

Ivo Bauer

unread,
Mar 9, 2004, 2:50:27 AM3/9/04
to
Good day!

I've got a pure Winsock2 API question. Is there a way to adjust send and
receive timeouts when using blocking sockets? The MS Sockets 2 help states
that SO_SNDTIMEO and SO_RCVTIMEO options are not supported. Is this true?


Best regards,
Ivo


Chad Z. Hower aka Kudzu

unread,
Mar 9, 2004, 4:48:16 AM3/9/04
to
"Ivo Bauer" <ba...@ozm.cz> wrote in news:404d773f$1...@newsgroups.borland.com:

> I've got a pure Winsock2 API question. Is there a way to adjust send and
> receive timeouts when using blocking sockets? The MS Sockets 2 help states
> that SO_SNDTIMEO and SO_RCVTIMEO options are not supported. Is this true?

Correct. Indy implements its own read timeouts without the need for these.


--
Chad Z. Hower (a.k.a. Kudzu) - http://www.hower.org/Kudzu/
"Programming is an art form that fights back"

Want to keep up to date with Indy?

Join Indy News - it free!

http://www.atozed.com/indy/news/

Atle Smelvær

unread,
Mar 9, 2004, 5:47:31 AM3/9/04
to
Yes, but what happens when a connection is cut in the middle of a transfer.
And it's cut at a point where no signal is sendt back to inform about it.
Then you would be inside the recv call, and there you will not have your
readtimeout. Because Indy only use timeout on the "select" call before
calling recv. Then you will have the default timeout always, with no easy
way to change it.

I made a little hack inside my units like this:

GStack.WSSetSockOpt(TIdSocketHandleHack(TIdIOHandlerSocket(FConnection.IOHan
dler).Binding).FHandle,0,Id_SO_SNDTIMEO,@Value,SizeOf(Value));
GStack.WSSetSockOpt(TIdSocketHandleHack(TIdIOHandlerSocket(FConnection.IOHan
dler).Binding).FHandle,0,Id_SO_RCVTIMEO,@Value,SizeOf(Value));

I just made a new class descendant TIdSocketHandleHack from TIdSocketHandle
to get into the protected area of this object.


Atle Smelvær

unread,
Mar 9, 2004, 7:58:18 AM3/9/04
to
Winsock2 supports SO_SNDTIMEO and SO_RCVTIMEO


Ivo Bauer

unread,
Mar 9, 2004, 8:14:12 AM3/9/04
to
"Atle Smelvćr" <at...@datagrafikk.no> píše v diskusním příspěvku
news:404dbf6a$1...@newsgroups.borland.com...

> Winsock2 supports SO_SNDTIMEO and SO_RCVTIMEO

Sure? Your and Chad's replies quite differ, though. Does that mean that I
could be able to adjust my own send and receive timeouts for blocking socket
send and recv operations?

Just one more question. How about adjusting a connect timeout on the client
side for a blocking socket? Any idea?

Thanks to both for your replies.

Best regards,
Ivo


Atle Smelvær

unread,
Mar 9, 2004, 8:28:51 AM3/9/04
to
Versions before 2.0 does not support SO_SNDTIMEO and SO_RCVTIMEO. From 2.0
they are supported. You could use the little hack that I posted to get to
the socket handle inside the Indy connection object.

Indy has already implemented a connect timeout
(YourConnection.Connect(yourtimeout). Use that one when connecting.

-Atle


Sercan Oz

unread,
Mar 9, 2004, 7:56:35 PM3/9/04
to
Hi

Try this code.

procedure settimeout
var
FDSet: TFDSet;
Timeout : TTimeVal;
begin
Timeout.tv_sec := 5 ; **second or use tv_usec
FD_ZERO(FDSet);
FD_SET(soket, FDSet);
select(soket, @FDSet, nil, nil, @Timeout);

for receive...
setsockopt(Soket,SOL_SOCKET,SO_RCVTIMEO,@timeout,sizeof(timeout))

for send use : SO_SNDTIMEO

Best regards
Sercan

"Atle Smelvær" <at...@datagrafikk.no> wrote in message
news:404d...@newsgroups.borland.com...

Ivo Bauer

unread,
Mar 9, 2004, 2:20:21 PM3/9/04
to
"Atle Smelvćr" <at...@datagrafikk.no> píše v diskusním příspěvku
news:404d...@newsgroups.borland.com...

> Versions before 2.0 does not support SO_SNDTIMEO and SO_RCVTIMEO. From 2.0
> they are supported.

Ok, I acknowledge this.


> Indy has already implemented a connect timeout
> (YourConnection.Connect(yourtimeout). Use that one when connecting.

So in case of a blocking sockets, there is no smart way of adjusting the
connect timeout other than spawning a background thread, make the connection
in its context and terminate & wait for it to finish as soon as the timeout
has elapsed?


Best regards,
Ivo


Ivo Bauer

unread,
Mar 9, 2004, 2:42:21 PM3/9/04
to
"Sercan Oz" <ozse...@ttnet.net.tr> píše v diskusním příspěvku
news:404d...@newsgroups.borland.com...
> Hi
>
> Try this code.


Thanks a lot,
Ivo


Remy Lebeau (TeamB)

unread,
Mar 9, 2004, 3:05:09 PM3/9/04
to
"Ivo Bauer" <ba...@ozm.cz> wrote in message
news:404e...@newsgroups.borland.com...

> So in case of a blocking sockets, there is no smart way
> of adjusting the connect timeout other than spawning a
> background thread, make the connection in its context
> and terminate & wait for it to finish as soon as the timeout
> has elapsed?

You don't need to perform the actual connecting from the background thread.
You can leave that in the calling thread with the rest of the socket
operations. The trick is just to disconnect the socket from a thread other
than the connecting thread. The background thread runs the timer and then
the disconnect it performs if elapsed will cause the connect in the original
thread to fail. That is what Indy does internally. No, there is no other
way to implement a decent connect timeout with blocking sockets. The native
connect timeout for a socket is not user-configurable, it is hard-coded in
the vendor-specific transport library.


Gambit


Ivo Bauer

unread,
Mar 9, 2004, 2:47:56 PM3/9/04
to
"Atle Smelvćr" <at...@datagrafikk.no> píše v diskusním příspěvku
news:404d...@newsgroups.borland.com...

> Indy has already implemented a connect timeout
> (YourConnection.Connect(yourtimeout). Use that one when connecting.

Just an idea: Wouldn't it be possible to initially create a socket as
non-blocking, call "connect" immediately follwed by a call to "select" in
order to wait for the connection process being finished within the specified
timeout, and then *turn* this socket into blocking? Somewhere in the
Winsock2 Help I read that this is somehow possible but unfortunately don't
remember what needs to be done to accomplish this task. Can anybody shed
some light on this problem?


Thanks in advance,
Ivo


Ivo Bauer

unread,
Mar 9, 2004, 3:15:32 PM3/9/04
to
"Remy Lebeau (TeamB)" <gambit47...@no.spam.yahoo.com> píše v diskusním
příspěvku news:404e2164$1...@newsgroups.borland.com...

> You don't need to perform the actual connecting from the background
thread.
> You can leave that in the calling thread with the rest of the socket
> operations. The trick is just to disconnect the socket from a thread
other
> than the connecting thread. The background thread runs the timer and then
> the disconnect it performs if elapsed will cause the connect in the
original
> thread to fail. That is what Indy does internally.

That sounds logical to me but I've just looked into Indy sources (v9.0.14)
and discovered that TIdIOHandlerSocket.ConnectClient method calls the local
method named ConnectTimeout which spawns an instance of TIdPeerThread which
in turn calls FBinding.Connect in its Execute method. Since FBinding is of
type TIdSocketHandle, it looks like its connect method calls WSConnect
method of GStack for performing actual connection. Or do I understand it
wrong?


> No, there is no other
> way to implement a decent connect timeout with blocking sockets. The
native
> connect timeout for a socket is not user-configurable, it is hard-coded in
> the vendor-specific transport library.

It's a shame. It should definitely be a built-in feature of Winsock2 for
blocking sockets.


Best regards,
Ivo


Remy Lebeau (TeamB)

unread,
Mar 9, 2004, 3:42:14 PM3/9/04
to

"Ivo Bauer" <ba...@ozm.cz> wrote in message
news:404e...@newsgroups.borland.com...

> That sounds logical to me but I've just looked into Indy sources


> (v9.0.14) and discovered that TIdIOHandlerSocket.ConnectClient
> method calls the local method named ConnectTimeout which
> spawns an instance of TIdPeerThread which in turn calls
> FBinding.Connect in its Execute method.

The reason Indy does the connecting in the background thread is to support
TIdAntiFreeze, which is useless if invoked from a worker thread. So the
logic is reversed - Indy does the connecting in a worker thread and run its
timeout code in the main calling thread, allowing TIdAntiFreeze to operate
periodically if needed. That is ok, though, because if the timeout elapses,
the worker thread is still terminated and the socket disconnected from a
thread other than the one that is performing the actual connecting.


Gambit


Ivo Bauer

unread,
Mar 9, 2004, 5:40:25 PM3/9/04
to
"Remy Lebeau (TeamB)" <gambit47...@no.spam.yahoo.com> píše v diskusním
příspěvku news:404e2a16$1...@newsgroups.borland.com...

> The reason Indy does the connecting in the background thread is to support
> TIdAntiFreeze, which is useless if invoked from a worker thread. So the
> logic is reversed - Indy does the connecting in a worker thread and run
its
> timeout code in the main calling thread, allowing TIdAntiFreeze to operate
> periodically if needed. That is ok, though, because if the timeout
elapses,
> the worker thread is still terminated and the socket disconnected from a
> thread other than the one that is performing the actual connecting.

Thanks a lot, Remy, for the clarification.


Best regards,
Ivo


Marc Guillot

unread,
Mar 10, 2004, 9:06:45 AM3/10/04
to
I have a similar problem.

I have a TIdFtp (Indy 9.0.14), I can specify ReadTimeOut, but I cannot
specify a WriteTimeOut. When sending files to FTP Server, sometimes
application freezes doing nothing (in ftp server I can see the new file, but
even is 0 bytes size).

I will like to use this code to specify a WriteTimeOut, but I don't
understand it. ż What's soket ?. The only Indy Component I have is a TIdFtp.

> procedure settimeout
> var
> FDSet: TFDSet;
> Timeout : TTimeVal;
> begin
> Timeout.tv_sec := 5 ; **second or use tv_usec
> FD_ZERO(FDSet);
> FD_SET(soket, FDSet);
> select(soket, @FDSet, nil, nil, @Timeout);
>
> for receive...
> setsockopt(Soket,SOL_SOCKET,SO_RCVTIMEO,@timeout,sizeof(timeout))
>
> for send use : SO_SNDTIMEO

Thanks a lot.


Marc Guillot

unread,
Mar 10, 2004, 9:32:36 AM3/10/04
to
I'am trying :

procedure TdmReplicacion.EstablirTimeOut;


var FDSet: TFDSet;
Timeout : TTimeVal;

Soket: integer;
begin
Soket := ftpCom.Socket.Binding.Handle;
Timeout.tv_sec := 30;
FD_ZERO(FDSet);
FD_SET(Soket, FDSet);
select(Soket, @FDSet, nil, nil, @Timeout);
setsockopt(Soket, SOL_SOCKET, SO_SNDTIMEO, @Timeout, sizeof(Timeout));
setsockopt(Soket, SOL_SOCKET, SO_RCVTIMEO, @timeout, sizeof(timeout));
end;

Being ftpCom the TIdFtp component. Is this right ?

Thank you.


Remy Lebeau (TeamB)

unread,
Mar 10, 2004, 3:36:05 PM3/10/04
to

"Marc Guillot" <guill...@iespana.es> wrote in message
news:404f...@newsgroups.borland.com...

> When sending files to FTP Server, sometimes application
> freezes doing nothing

Then you need to either 1) move the TIdFTP to its own thread, or 2) use
TIdAntiFreeze


Gambit


Marc Guillot

unread,
Mar 11, 2004, 7:20:19 AM3/11/04
to
Thanks for your interest.


> Then you need to either 1) move the TIdFTP to its own thread, or 2) use
> TIdAntiFreeze

How this will help to make a write TimeOut ?. There is not a problem that
applitatcion freezes until sending file ends, my problem is when
applicationn freezes sending nothing. So I will like to have a Write TimeOut
to detect it.


Remy Lebeau (TeamB)

unread,
Mar 11, 2004, 2:21:46 PM3/11/04
to

"Marc Guillot" <guill...@iespana.es> wrote in message
news:4050...@newsgroups.borland.com...

> How this will help to make a write TimeOut ?

It doesn't. But it will help the application stop freezing during
transfers.

> There is not a problem that applitatcion freezes until sending
> file ends, my problem is when applicationn freezes sending
> nothing. So I will like to have a Write TimeOut to detect it.

If nothing is being sent at all, then you have a much larger problem, as you
are somehow deadlocking the socket code, which write timeouts is not going
to fix. You need to fix the underlying deadlock itself. Then you shouldn't
need to worry about write timeouts at all.


Gambit


Chad Z. Hower aka Kudzu

unread,
Mar 13, 2004, 2:47:27 PM3/13/04
to
"Atle Smelv r" <at...@datagrafikk.no> wrote in
news:404d...@newsgroups.borland.com:
> Yes, but what happens when a connection is cut in the middle of a
> transfer. And it's cut at a point where no signal is sendt back to
> inform about it. Then you would be inside the recv call, and there you
> will not have your readtimeout. Because Indy only use timeout on the
> "select" call before calling recv. Then you will have the default
> timeout always, with no easy way to change it.

If you read the Indy docs you'll notice that its a "lag" timeout, not a total
timeout.

Also yes, if the connection is disconencted you wont get a timeout. You'll
get a disconnect exception, which is what should happen.

--
Chad Z. Hower (a.k.a. Kudzu) - http://www.hower.org/Kudzu/
"Programming is an art form that fights back"

Want more Indy stuff? Try the Atozed Indy Portal at
http://www.atozedsoftware.com/
* More Free Demos
* Free Articles
* Extra Support

Chad Z. Hower aka Kudzu

unread,
Mar 13, 2004, 2:48:14 PM3/13/04
to
"Ivo Bauer" <ba...@ozm.cz> wrote in news:404d...@newsgroups.borland.com:

> Sure? Your and Chad's replies quite differ, though. Does that mean that
> I could be able to adjust my own send and receive timeouts for blocking
> socket send and recv operations?

Mine might be wrong regarding Windows. Had a long day and I remember some
discussion on the internal list regarding this. I think possibly certain
versions of Windows support it and others may not.

--
Chad Z. Hower (a.k.a. Kudzu) - http://www.hower.org/Kudzu/
"Programming is an art form that fights back"

Want to keep up to date with Indy?

Chad Z. Hower aka Kudzu

unread,
Mar 13, 2004, 2:46:17 PM3/13/04
to
"Ivo Bauer" <ba...@ozm.cz> wrote in news:404e...@newsgroups.borland.com:

> Just an idea: Wouldn't it be possible to initially create a socket as
> non-blocking, call "connect" immediately follwed by a call to "select"
> in order to wait for the connection process being finished within the

Yes - but how will that help a read/write timeout? This woudl be a connect
timeout, which Indy already has.


--
Chad Z. Hower (a.k.a. Kudzu) - http://www.hower.org/Kudzu/
"Programming is an art form that fights back"

Qualified help FAST with Indy Experts Support
from the experts themselves:

http://www.atozed.com/indy/experts/support.iwp

Atle Smelvær

unread,
Mar 15, 2004, 8:10:18 AM3/15/04
to
I don't need to read the Indy doc. I just told you how it works, so I would
know that. I was also not complaining about any documentation. Just telling
about a problem with the current implementation.

When using blocking sockets that implement some IsAlive functionality of its
own, it's important that the readtimeout works as it should. That way you
can use the readtimeout instead of creating another timeout thread, and
still get it to kill the connection at the right time even if the connection
was cut without a disconnect signal.


Marc Guillot

unread,
Mar 17, 2004, 5:41:25 AM3/17/04
to
> If nothing is being sent at all, then you have a much larger problem, as
you
> are somehow deadlocking the socket code, which write timeouts is not going
> to fix. You need to fix the underlying deadlock itself. Then you
shouldn't
> need to worry about write timeouts at all.

Ok. Thank you.


0 new messages