How to get open tcp connections?

Hi, using Delphi 12 and latest RO sdk.
We use TROHttpServer and noted that sometimes, when the server is busy, lots of TCP connections remains open or waiting and it didn’t go away (the only way to get rid of them is to bring server down and up).
We captured those connections (attached).
Is there a way to get information about those connections (IP/port) inside TROHttpServer in order to verify what each connection was doing?

My ideia is to map those ip/port with information gathered from onGetDispatchInfo event to see where is the bottleneck.

Hi,

I don’t think, that you can do anything with this connection inside TROHttpServer because this state come from Windows Sockets API (WinSock2).

You can disable KeepConnection on client-side or KeepAlive on server-side. it may improve situation and connections may be closed often but also can decrease performance.

by default, we have 180 sec as keep-alive timeout.

Hi, keepAlive is on/off or it’s a numeric value? why could it decrease performance?

Hi,

this is boolean value.

httpserver.KeepAlive:

KeepAlive

Controls whether to use HTTP Keep-Alive to keep the connection alive between requests.
If enabled (true) , once a request is made and a connection is established, this connection is kept open and used for future requests.
If disabled, the connection is closed, and a new connection is created for future requests.
Since establishing a connection is - relatively speaking - a costly and resource intensive operation for the network, compared to sending small amounts of data, it is recommended to keep this option enabled for optimal performance, if requests to the server are done relatively frequently.
For Keep-Alive to work, the option must be supported and enabled on both client and server.

property KeepAlive: Boolean read write default True

in brief:

  • true - existing connection can be reused for next request but it will be in ESTABLISHED state.
  • false - a new connection should be created for new request and it may take some time.

For background, with KeepAlive turned off, every time a client makes an HTTP request to a server, it establishes a TCP connection, sends its request, receives a response, and then the connection is terminated. If the same client then makes a second request to the same server, it starts from scratch and establishes a new connection.

By contract, with KeepAlive on, the connection stays around (for a certain while, or potentially until the client actively disconnects because it’s “done”), so subsequent requests can use the same connection, saving time and network resources.

Think of it as us having a conversation via the phone. With KeepAlive off, every time I have a question, I call you, wait for your answer, and hang up. If I have a follow-up question, I pick up the phone again and call you again. Extra time is spent by me dialing, the phone company finding the right cell tours, by the phone ringing, and by you having to get off the couch, walk to it, and pick it up. With KeepAlive on, we just keep talking until we have nothing else to say, and then hang up.

So KeepAlive makes sense if a client app expects to talk a lot to the server in one go. If instead the client just needs to make one request and then it’s done for the next – say minute or hours or more – the system overall is better served by not keeping the connection alive (uselessly).

OK, great explanation from you all! Thanks for that.
Here, when we have a busy server, the number of CLOSE_WAIT connections grows and server starts to slow down. Sometimes, we have to reset it in order to work.
So, we started to investigate what clients are doing. To do that, we captured RORemoteDataModuleGetDispatchInfo in order to log which function each user is requesting.
In order to map more easily with opened TCP/IP connection, is there a way to get those connections from TRoHttpServer?

1 Like

Hi,

You can try to use workaround with TcpTimedWaitDelay from https://superuser.com/questions/67039/how-to-kill-windows-zombie-tcp-connections :

CLOSE_WAIT means that the connection was closed on the other end.

Evidently, beyondtv doesn’t detect this condition and continues to send data to the application on the other end. The other end can’t send anything back over this connection, since it has closed its end of the connection.

The solution is to set the TcpTimedWaitDelay entry in

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\tcpip\Parameters

This entry determines the time that must elapse before TCP can release a closed connection and reuse its resources. This interval between closure and release is known as the TIME_WAIT state or 2MSL state. During this time, the connection can be reopened at much less cost to the client and server than establishing a new connection.

By default on my machine, this contains the value of -1, which I take to mean that closed connections are never released, which is exactly the behavior that you’re observing.

I suggest that you set the value of this entry in the allowed range of 30–300 seconds. I suppose that 300 seconds = 5 minutes is entirely sufficient for your case, where it takes 40 minutes to freeze out your computer.

read more at Settings that can be Modified to Improve Network Performance - BizTalk Server | Microsoft Learn