在 C++ 中实现心跳的最佳方法是什么? 检查套接字连接?

发布于 2024-07-12 10:58:47 字数 212 浏览 9 评论 0原文

嘿,帮派。 我刚刚使用 sys/socket 用 C++ 编写了客户端和服务器。 我需要处理客户端仍处于活动状态但服务器已关闭的情况。 一种建议的方法是使用心跳定期断言连接。 如果没有尝试在 Y 时间段内每 X 秒重新连接一次,然后超时。

这种“心跳”是检查连接的最佳方式吗?

我正在使用的套接字可能有相关信息,有没有办法检查是否存在连接而不扰乱缓冲区?

Hey gang. I have just written a client and server in C++ using sys/socket. I need to handle a situation where the client is still active but the server is down. One suggested way to do this is to use a heartbeat to periodically assert connectivity. And if there is none to try to reconnect every X seconds for Y period of time, and then to time out.

Is this "heartbeat" the best way to check for connectivity?

The socket I am using might have information on it, is there a way to check that there is a connection without messing with the buffer?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

音盲 2024-07-19 10:58:47

如果您在 IP 网络上使用 TCP 套接字,则可以使用 TCP 协议的 keepalive 功能,该功能将定期检查套接字以确保另一端仍然存在。 (这还有一个优点,可以使套接字的转发记录在客户端和服务器之间的任何 NAT 路由器中保持有效。)

这是一个 TCP keepalive 概述,其中概述了您可能想要使用 TCP keepalive 的一些原因; 此特定于 Linux 的 HOWTO 描述了如何配置套接字以使用 TCP keepalive在运行时。

看起来您可以通过使用 WSAIoctl() 函数。

如果您使用 IP 上的 UDP 套接字,则需要在协议中构建您自己的心跳。

If you're using TCP sockets over an IP network, you can use the TCP protocol's keepalive feature, which will periodically check the socket to make sure the other end is still there. (This also has the advantage of keeping the forwarding record for your socket valid in any NAT routers between your client and your server.)

Here's a TCP keepalive overview which outlines some of the reasons you might want to use TCP keepalive; this Linux-specific HOWTO describes how to configure your socket to use TCP keepalive at runtime.

It looks like you can enable TCP keepalive in Windows sockets by setting SIO_KEEPALIVE_VALS using the WSAIoctl() function.

If you're using UDP sockets over IP you'll need to build your own heartbeat into your protocol.

惜醉颜 2024-07-19 10:58:47

是的,这心跳就是最好的办法。 您必须将其构建到服务器和客户端用于通信的协议中。

最简单的解决方案是让客户端定期发送数据,如果服务器在特定时间段内没有收到客户端的任何数据,则关闭连接。 这非常适合客户端发送查询而服务器发送响应的查询/响应协议。

例如,您可以使用以下方案:

  1. 服务器响应每个查询。 如果服务器两分钟内没有收到查询,则会关闭连接。

  2. 客户端发送查询并在每次发送后保持连接打开。

  3. 如果客户端在一分钟内没有发送查询,它会发送“are you there”查询。 服务器响应“是的,我是”。 这会重置服务器的两分钟计时器,并向客户端确认连接仍然可用。

如果客户端在过去一分钟不需要发送查询,那么让客户端关闭连接可能会更简单。 由于所有操作都是由客户端发起的,因此如果需要执行新操作,它总是可以打开一个新连接。 这将其简化为:

  1. 如果服务器在两分钟内未收到查询,则服务器将关闭连接。

  2. 如果客户端在一分钟内不需要发送查询,则关闭连接。

但是,这并不能向客户端保证服务器始终存在并准备好接受查询。 如果您需要此功能,则必须在协议中实现“您在吗”“是的我在”查询/响应。

Yes, this heartbeat is the best way. You'll have to build it into the protocol the server and client use to communicate.

The simplest solution is to have the client send data periodically and the server close the connection if it hasn't received any data from the client in a particular period of time. This works perfectly for query/response protocols where the client sends queries and the server sends responses.

For example, you can use the following scheme:

  1. The server responds to every query. If the server does not receive a query for two minutes, it closes the connection.

  2. The client sends queries and keeps the connection open after each one.

  3. If the client has not send a query for one minute, it sends an "are you there" query. The server responds with "yes I am". This resets the server's two minutes timer and confirms to the client that the connection is still available.

It may be simpler to just have the client close the connection if it hasn't needed to send a query for the past minute. Since all operations are initiated by the client, it can always just open a new connection if it needs to perform a new operation. That reduces it to just this:

  1. The server closes the connection if it hasn't received a query in two minutes.

  2. The client closes the connection if it hasn't needed to send a query in one minute.

However, this doesn't assure the client that the server is present and ready to accept a query at all times. If you need this capability, you will have to implement an "are you there" "yes I am" query/response into your protocol.

信仰 2024-07-19 10:58:47

如果另一端已经离开(即进程已终止、机器已停机等),则尝试从套接字接收数据将导致错误。 然而,如果另一侧只是挂起,插座将保持打开状态。 在这种情况下,心跳是有用的。 确保您使用的任何协议(在 TCP 之上)都支持某种“不执行任何操作”的请求或数据包 - 每一方都可以使用它来跟踪上次从另一方收到某些内容的时间,然后可以如果数据包之间经过的时间过长,则关闭连接。

请注意,这是假设您使用的是 TCP/IP。 如果您使用 UDP,那就完全是另一回事了,因为它是无连接的。

If the other side has gone away (i.e. the process has died, the machine has gone down, etc.), attempting to receive data from the socket should result in an error. However if the other side is merely hung, the socket will remain open. In this case, having a heartbeat is useful. Make sure that whatever protocol you are using (on top of TCP) supports some kind of "do-nothing" request or packet - each side can use this to keep track of the last time they received something from the other side, and can then close the connection if too much time elapses between packets.

Note that this is assuming you're using TCP/IP. If you're using UDP, then that's a whole other kettle of fish, since it's connectionless.

我是男神闪亮亮 2024-07-19 10:58:47

好吧,我不知道你的程序是做什么的,所以也许这不可行,但我建议你避免尝试始终保持套接字打开。 仅当您使用它时才应打开它,不使用时应将其关闭。

如果您在读取和写入之间等待用户输入,请关闭套接字。 设计您的客户端/服务器协议(假设您手动执行此操作并且不使用任何标准协议(如 http 和/或 SOAP)来处理此问题。

如果连接断开,套接字将会出错; 编写您的程序,以便在写入套接字期间发生此类错误时不会丢失任何信息,并且在从套接字读取期间发生错误时不会获得任何信息。 事务性和原子性应该纳入您的客户端/服务器协议中(同样,假设您自己设计它)。

Ok, I don't know what your program does or anything, so maybe this isn't feasible, but I suggest that you avoid trying to always keep the socket open. It should only be open when you are using it, and should be closed when you are not.

If you are between reads and writes waiting on user input, close the socket. Design your client/server protocol (assuming you're doing this by hand and not using any standard protocols like http and/or SOAP) to handle this.

Sockets will error if the connection is dropped; write your program such that you don't lose any information in the case of such an error during a write to the socket and that you don't gain any information in the case of an error during a read from the socket. Transactionality and atomicity should be rolled into your client/server protocol (again, assuming you're designing it yourself).

仙女 2024-07-19 10:58:47

也许这会对您有所帮助,TCP Keepalive HOWTO
或这个 SO_SOCKET

maybe this will help you, TCP Keepalive HOWTO
or this SO_SOCKET

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文