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
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!
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.
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
Indy has already implemented a connect timeout
(YourConnection.Connect(yourtimeout). Use that one when connecting.
-Atle
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...
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
Thanks a lot,
Ivo
> 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
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
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
> 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
Thanks a lot, Remy, for the clarification.
Best regards,
Ivo
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.
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.
> 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
> 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.
> 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
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
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?
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:
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.
Ok. Thank you.