Jump to content
PizzaProgram

Cannot change SocketFamily when not closed or in DNS lookup

Recommended Posts

I would like to ask for a tiny help, because I do not know ICS well enough yet to find a solution for this... 👼

 

I've switched from Indy to ISC a few weeks ago. It runs only on a few PCs yet so I can test it's durability.
But it's not stable enough yet, because sometimes, when the server is temporary overloaded I experience a strange behaviour:
 (By "sometimes" I mean after a few days of run. So I can not debug it, only read the logs of clients on remote PCs.)

 

1. failing attempt:

  • httpGET: Error #8 -- Request aborted on timeout

2. attempt: (after 20 sec)

  • 0 byte answer, no error msg.

3., 4., 5., ... all the attempts after that:

  • httpGET: Status #404 -- Cannot change SocketFamily when not closed or in DNS lookup
  • httpGET: Status #404 -- Cannot change SocketFamily when not closed or in DNS lookup
  • httpGET: Status #404 -- Cannot change SocketFamily when not closed or in DNS lookup
  • ... forever

 

... and the only way I can fix it, by restarting the program.

Here I've shared my code using TSslHttpCli before:

 

 

I was told not to destroy and recreate ICS component every each time before using it, like I did with Indy.
But in that case:

  • Why ICS does not reset itself / the socket, after first (timeout) error ?
  • Do I have to create: some kind of "onTimeout" function for it manually, and close the socket myself?
    (I'm guessing that the socket is still open, and that's why it's causing trouble to re-connect. Right?)
  • Why does my function's Result is True after such error, while the "error" text is clearly showing there was a big problem with the request?
    (The only case this can happen, if Statuscode is 200 or 400. Not #8 or none or #404.)
  • Do I have to set:
    SslHttpCli3.StatusCode := 0;
    each time myself before calling .GET ? (Otherwise I do not see, why I do get a "True" as result.)

 

Thank you very much in forward for any insight / help / idea !🙂

Share this post


Link to post

If your error handling code does not correctly clean up after errors, you can check ,

 

Before starting a new request, you can check State <> wsClosed before starting a request and close it.  Beware, Close may not be instant, if Windows is still attempting to connect.

 

Angus

 

 

Share this post


Link to post

Closing the socket every each time before a new REST request, kills the concept of :

  • "do not have to re-re-re-reconnect to the same server and re-re-reinitialize SSL".

I think it would be logical to keep the socket as long as it works, (sometimes for days), but kill it when there was an error.

That was my question about:

  • Do I have to take care of that manually by default?
  • Or did I find a bug in the component that is very hard to reproduce?

 

How about something like this?

try
  SslHttpCli3.StatusCode := 0;
  SslHttpCli3.Get;
except on E:Exception do begin 
  errorTxt := E.Message;
  try SslHttpCli3.CtrlSocket.Close; except end;
end; end;

 

Share this post


Link to post

You are not using the modern REST component TSslHttpRest, but the older harder to use component TSslHttpCli, your choice, but you have to live with more complex code.

 

The point here is that you are responsible for determining whether you successfully connected to the HTTP server, and cleanly close everything if not, and try again.

 

ICS is event driven, it does not wait x seconds and then decide to clean everything up for you, not even the sync modes.

 

There will be no breaking changes to the way the HTTP client handles errors, without weeks of discussion.  You need to handle this yourself.

 

Angus

 

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×