Best practice: Keep TCP/IP connection open or close it after each transfer?

16,075

Solution 1

I would suggest a mix of the two. When a new connection is opened, start an idle timer for it. Whenever data is exchanged, reset the timer. If the timer elapses, close the connection (or send a command to the client asking if it wants the connection to remain open). If the connection has been closed when data needs to be sent, open a new connection and repeat. This way, less-often-used connections can be closed periodically, while more-often-used connections can stay open.

Solution 2

Two Cents from experiment...

My first TCP/IP client/server application was using a new connection and a new thread for each request... years ago...

Then I discovered (using ProcessExplorer) that it consummed some network resources because all closed connection are indeed not destroyed, but remain in a particular state for some time. A lot of threads were created...

I even had some connection problems with a lot of concurent requests: I didn't have enough ports on my server!

So I rewrote it, following the HTTP/1.1 scheme, and the KeepAlive feature. It's much more efficient, use a small number of threads, and ProcessExplorer likes my new server. And I never run out of port again. :)

If the client has to be shutdown, I'll use a ThreadPool to, at least, don't create a thread per client...

In short: if you can, keep your client connections alive for some minutes.

Solution 3

While it may be fine to connect and disconnect for an application that is active once every few minutes, the application that is communicating several times a second will see a performance boost by leaving the connection open.

Additionally, your code will be much simple if you aren't trying to constantly open, close, or diagnose an open connection. With the proper open and close logic, and SEH around your read and writes, there's no reason to test if the socket is still connected before using, just use it. It will tell you when there is a problem.

I'd lean towards keeping a single connection open in most enterprise applications. It generally will lead to cleaner code, that is easier to maintain.

/twocents

Solution 4

Unless you are scaling to many hundreds of concurrent connections I would definitely keep it open - this is by far the better of the two options. Once you scale past hundreds into thousands of concurrent connections you may have to drop and reconnect. I have architected my entire framework around this (http://www.csinnovations.com/framework_overview.htm) since it allows me to "push" data to the client from the server whenever required. You need to write a fair bit of code to ensure that the connection is up and working (network drop-outs, timed pings, etc), but if you do this in your "framework" then your application code can be written in such a way that you can assume that the connection is always "up".

Share:
16,075
vikas mehta
Author by

vikas mehta

Updated on June 14, 2022

Comments

  • vikas mehta
    vikas mehta almost 2 years

    My Server-App uses a TIdTCPServer, several Client apps use TIdTCPClients to connect to the server (all computers are in the same LAN).

    Some of the clients only need to contact the server every couple of minutes, others once every second and one will do this about 20 times a second.

    If I keep the connection between a Client and the Server open, I'll save the re-connect, but have to check if the connection is lost.

    If I close the connection after each transfer, it has to re-connect every time, but there's no need to check if the connection is still there.

    What is the best way to do this?

    At which frequency of data transfers should I keep the connection open in general?

    What are other advantages / disadvantages for both scenarios?

  • Misha
    Misha about 13 years
    Remy, nice work on Indy over the last few years ;-) I use the TCP components of Indy extensively, and I mean extensively, as an intrinsic part of my distributed application framework. You may want to take a look at it.
  • Victoria
    Victoria almost 7 years
    Although OS thread pool I would rather see implemented in Indy servers (rather than per client thread), what you claim here is not correct - see e.g. blogs.msdn.microsoft.com/oldnewthing/20050729-14/?p=34773
  • Jonathan Elkins
    Jonathan Elkins almost 6 years
    @Remy Lebau how do you close the connection? I'm new to Indy.
  • Remy Lebeau
    Remy Lebeau almost 6 years
    @JonathanElkins use the connection's Disconnect() method. It is available on both client (TIdTCPClient.Disconnect()) and server (AContext.Connection.Disconnect() inside a server event).