Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How to abort TIdImap4.Connect?
#1
As we know, we can abort any TIdTCPConnection child classes in the OnWork event, including the TidImap4 client component.

But how to abort the connection before the timeout value is reached? 

Thanks.
Reply
#2
(11-14-2018, 05:56 AM)edwinyzh Wrote: how to abort the connection before the timeout value is reached?

Several events are triggered by TIdTCPClient.Connect() (in this order):

- OnBeforeBind
- OnSocketAllocated
- OnAfterBind
- OnStatus(hsResolving) ¹
- OnStatus(hsConnecting) ²
- OnStatus(hsConnected)
- OnConnected

You can raise an exception from any of those events.

¹ during the hsResolving stage, there is currently no way to abort a hostname lookup.  You just have to let it play out on its own.  Otherwise, do your own lookup, such as via TIdDNSResolver, and assign only IP addresses to TIdTCPClient.

² The ConnectTimeout properly applies to the hsConnecting stage only.  During that stage, to abort the connection prematurely, you must close the underlying socket directly (which is what Connect() does when the timeout elapses).  You can close the socket at any time after the OnSocketAllocated event has been triggered, such as by calling TIdTCPClient.Socket.Binding.CloseSocket() ³.

³ I suppose calling TIdTCPClient.Disconnect() would also work, though it does Close() the IOHandler (which has threading issues for TIdSSLIOHandlerSocketOpenSSL), and it also triggers the OnStatus(hsDisconnecting), OnDisconnected, and OnStatus(hsDisconnected) events.  I think for purposes of aborting a connection in progress, using CloseSocket() would be a safer choice.

Reply
#3
rlebeau,

Thanks for the help info.
I just browsed the Indy source code, it seems that the uninterruptible time range is in between OnStatus(hsConnecting) and OnStatus(hsConnected), where you have no way to abort until the timeout's reached?

It seems that there is no other way except using a smaller timeout value.
Reply
#4
(11-15-2018, 04:36 AM)edwinyzh Wrote: I just browsed the Indy source code, it seems that the uninterruptible time range is in between OnStatus(hsConnecting) and OnStatus(hsConnected), where you have no way to abort until the timeout's reached?

That is not true. As I already explained in my previous reply, that time range IS interruptible. You just need to close the underlying socket itself to do so.

Between hsConnecting and hsConnected is when Indy is making the actual connection to the server (and is the only time when ConnectTimeout takes effect). If the socket is closed before the underlying socket API connect() is called, the connection fails with an "invalid socket" error. If the socket API connect() is already in progress when the socket is closed, the connection gets aborted with an appropriate error. Either way, the end result is the same - the API connect() fails, the connecting thread gets terminated, and TIdTCPClient.Connect() sees that and raises an exception into your code (typically EIdSocketError or EIdConnectException).

The only time range that IS NOT interruptible is between hsResolving and hsConnecting, when Connect() is blocked on the OS performing a DNS lookup, and ConnectTimeout has no effect.

Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)