Jump to content
eivindbakkestuen

Address and port are already in use error after TIdHttp.Get

Recommended Posts

Here's an unusual one:

 

I'm using TIdHttp.Get(<IP:port of local network machine>\somepath) inside a short lived thread (if that matters); no specific ports or anything is set in the IdHttp instance before the call. The other day, we got a number of exceptions like below on this call. I'm just wondering if anybody else has seen it, or has an idea what may have caused it? Not intending to blame Indy here, at a guess the OS doesn't reuse ports quick enough (limited resource) or something of that nature. However as part of a customer critical system, it'd be good to know if there's anything that can be done about it? (forgot to say, the application runs many instances on a Terminal Server)

 

Exception: EIdCouldNotBindSocket
Message: Could not bind socket. Address and port are already in use.

Edited by eivindbakkestuen
added text

Share this post


Link to post

Do you have the http.request.connection set to 'keep-alive'? I've seen posts that indicate that it will prevent dropping the port.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Keep-Alive - There are options to limit the life time / number of uses. 

Is the TIdHttp properly disposed of?

 

Did you try something like TCPView (https://docs.microsoft.com/en-us/sysinternals/downloads/tcpview) to find out what holds the endpoints?

 

Share this post


Link to post

Wait a minute. A client should use a random port. Only the server needs fixed ports. So in theory you should be able to open thousands of http.Get in parallel. Do you set your client to use a fixed port as well?

Share this post


Link to post
18 hours ago, eivindbakkestuen said:

I'm using TIdHttp.Get(<IP:port of local network machine>\somepath) inside a short lived thread (if that matters); no specific ports or anything is set in the IdHttp instance before the call. The other day, we got a number of exceptions like below on this call. I'm just wondering if anybody else has seen it, or has an idea what may have caused it?

Are you reusing the same TIdHTTP object for multiple Get() calls?  Unless you are explicitly setting the TIdHTTP.BoundPort(Min|Max) properties, I don't see any other way you can get that error, unless you are creating so many connections that you are just exhausting the OS's available local ports over time.

Quote

Not intending to blame Indy here, at a guess the OS doesn't reuse ports quick enough (limited resource) or something of that nature.

Possibly.  Hard to say without seeing your actual code, or at least knowing how many threads you are using.

 

Edited by Remy Lebeau

Share this post


Link to post
3 hours ago, Remy Lebeau said:

Are you reusing the same TIdHTTP object for multiple Get() calls?  Unless you are explicitly setting the TIdHTTP.BoundPort(Min|Max) properties, I don't see any other way you can get that error, unless you are creating so many connections that you are just exhausting the OS's available local ports over time.

Possibly.  Hard to say without seeing your actual code, or at least knowing how many threads you are using.

 

 

The thread (and the TIdHTTP instance inside it) are destroyed as soon as the result of the Get() call is available. The number of threads would not have been great (less than 10) since this happened shortly after restarting the application. This exception never happened in the previous 3 months of intensive application use, hence I'm puzzled. 🙂

Share this post


Link to post
15 hours ago, eivindbakkestuen said:

The thread (and the TIdHTTP instance inside it) are destroyed as soon as the result of the Get() call is available. The number of threads would not have been great (less than 10) since this happened shortly after restarting the application. This exception never happened in the previous 3 months of intensive application use, hence I'm puzzled. 🙂

Are the TIdHTTP.BoundIP and TIdHTTP.BoundPort(Min|Max) properties set to '' and 0, respectively?  When the error happens, what is the actual value of the TIdHTTP.Socket.Binding.IP, TIdHTTP.Socket.Binding.Port, and TIdHTTP.Socket.Binding.ClientPort(Min|Max) properties?  They should also be '' and 0, respectively.  If they are not, then something weird is going on.  By default, TIdHTTP should be binding to local port 0, allowing it to use a random local ephemeral port assigned by the OS.  There should be no "address and port already in use" error for just 10 connections if they are all on random local ports.  Which implies that there may be a non-zero port being used explicitly somewhere.

Share this post


Link to post

Ah, your BoundIP reference got me thinking. After some sleuthing, It turns out that my client had been misinforming me; BoundIP was put into use some months ago, and I was told that version worked for them. In reality, they were still running an older version which did not set BoundIP, which then caused confusion when a new update was delivered and this error immediately triggered. Lesson: don't trust clients (check), always use exception stack tracing (check) and log everything (check).

 

 

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
×