最佳实践:每次传输后保持 TCP/IP 连接打开还是关闭?
我的服务器应用程序使用 TIdTCPServer,多个客户端应用程序使用 TIdTCPClients 连接到服务器(所有计算机都在同一 LAN 中)。
有些客户端只需每隔几分钟联系服务器一次,其他客户端则每秒一次,甚至每秒大约需要联系 20 次。
如果我保持客户端和服务器之间的连接打开,我将保存重新连接,但必须检查连接是否丢失。
如果我在每次传输后关闭连接,则每次都必须重新连接,但无需检查连接是否仍然存在。
最好的方法是什么?
一般情况下,我应该以何种频率的数据传输保持连接打开?
这两种情况还有哪些其他优点/缺点?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
我建议将两者结合起来。当新连接打开时,为其启动一个空闲计时器。每当交换数据时,重置计时器。如果计时器到期,则关闭连接(或向客户端发送命令询问是否希望连接保持打开状态)。如果需要发送数据时连接已关闭,则打开新连接并重复。这样,不常用的连接可以定期关闭,而常用的连接可以保持打开状态。
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.
实验的两分钱...
我的第一个 TCP/IP 客户端/服务器应用程序为每个请求使用一个新连接和一个新线程...几年前...
然后我发现(使用 ProcessExplorer)它消耗了一些网络资源,因为所有关闭的连接确实没有被破坏,而是保持在特定状态一段时间。创建了很多线程...
我什至在大量并发请求时遇到了一些连接问题:我的服务器上没有足够的端口!
所以我重写了它,遵循HTTP/1.1方案,并且
KeepAlive
功能。它效率更高,使用少量线程,而且 ProcessExplorer 喜欢我的新服务器。我再也没有用完港口。 :)如果客户端必须关闭,我将使用 ThreadPool 至少不要为每个客户端创建一个线程...
简而言之:如果可以的话,让客户端连接保持活动状态几分钟。
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.
虽然对于每隔几分钟活动一次的应用程序进行连接和断开连接可能没问题,但每秒通信多次的应用程序将通过保持连接打开来实现性能提升。
此外,如果您不尝试不断地打开、关闭或诊断打开的连接,您的代码将会非常简单。有了正确的打开和关闭逻辑,以及围绕读写的 SEH,就没有理由在使用之前测试套接字是否仍然连接,只需使用它即可。当出现问题时它会告诉你。
我倾向于在大多数企业应用程序中保持单个连接打开。它通常会导致更干净的代码,更容易维护。
/两美分
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
我想这完全取决于您的目标以及给定时间内服务器上发出的请求量,更不用说服务器上的可用带宽和硬件了。
您还需要考虑未来,将来是否有可能需要保持连接畅通?如果是这样,那么您已经回答了自己的问题。
我为一个项目实现了一个聊天系统,其中约有 50 人(人数每 2 个月增长一次)始终保持联系,除了聊天之外,还包括数据传输、使用某些命令进行数据库操作等。我的实现是保持从应用程序启动到应用程序关闭,与服务器的连接一直打开,到目前为止没有任何问题,但是如果由于某种原因失去连接,它会自动重新建立,一切都会完美地继续。
总的来说,我建议您尝试两者(保持连接打开并在使用后关闭它),看看哪一个最适合您的需求。
I guess it all depends on your goal and the amount of requests made on the server in a given time not to mention the available bandwidth and the hardware on the server.
You need to think for the future as well, is there any chance that in the future you will need connections to be left open? if so, then you've answered your own question.
I've implemented a chat system for a project in which ~50 people(the number is growing with each 2 months) are always connected and besides chatting it also includes data transfer, database manipulation using certain commands, etc. My implementation is keeping the connection to the server open from the application startup until the application is closed, no issues so far, however if a connection is lost for some reason it is automatically reestablished and everything continues flawlessly.
Overall I suggest you try both(keeping the connection open and closing it after it's being used) and see which fits your needs best.
除非您扩展到数百个并发连接,否则我肯定会保持它打开 - 这是迄今为止两个选项中更好的一个。一旦并发连接数从数百个扩展到数千个,您可能必须断开并重新连接。我已经围绕此构建了我的整个框架(http://www.csinnovations.com/framework_overview.htm)因为它允许我在需要时将数据从服务器“推送”到客户端。您需要编写相当多的代码来确保连接正常运行(网络中断、定时 ping 等),但如果您在“框架”中执行此操作,那么您的应用程序代码可以用这样的形式编写这样您就可以假设连接始终处于“启动”状态。
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".
问题是每个应用程序的线程限制,大约 1400 个线程。因此最多 1300 个客户端同时连接 +-。
The problem is the limit of threads per application, around 1400 threads. So max 1300 clients connected at the same time +-.
当作为客户端关闭连接时,您使用的端口将在一段时间内不可用。因此,在大容量时,您会使用不同端口的负载。对于任何重复的事情,我都会保持打开状态。
When closing connections as a client the port you used will be unavailable for a while. So at high volume you’re using loads of different ports. For anything repetitive i’d keep it open.