2009-01-30 27 views
8

嘿团伙。我刚刚使用sys/socket编写了C++中的客户端和服务器。我需要处理客户端仍处于活动状态但服务器已关闭的情况。一种建议的方法是使用心跳周期性地断开连接。并且如果在Y时间段内没有任何可以尝试重新连接每X秒,然后超时。在C++中实现心跳检查套接字连接的最佳方式是什么?

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

我使用的套接字可能有关于它的信息,有没有办法检查有没有连接缓冲区的连接?

回答

13

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

这是一个TCP keepalive overview,它概述了你可能想使用TCP keepalive的一些原因; this Linux-specific HOWTO描述如何配置您的套接字以在运行时使用TCP keepalive。

看起来您可以通过使用WSAIoctl()函数设置SIO_KEEPALIVE_VALS来在Windows套接字中启用TCP keepalive。

如果你通过IP使用UDP套接字,你需要在你的协议中建立你自己的心跳。

+0

这是一个非常糟糕的解决方案。 TCP Keepalive非常不灵活,无法控制发送频率。如果你对双方都有控制权,就像OP一样,只要将连接活性测试设计到你自己的协议中就可以了。 – 2012-09-24 18:19:32

+0

嘿,东西的链接 - tldp.org/HOWTO/TCP-Keepalive-HOWTO/overview.html似乎打破 – Coffee 2013-03-17 03:31:17

2

如果对方已经消失(即进程已经死亡,该机已经下降等),试图从套接字接收数据应该会导致错误。但是,如果另一侧只是悬挂,插座将保持打开状态。在这种情况下,心跳是有用的。确保你使用的任何协议(在TCP之上)都支持某种“无所事事”请求或数据包 - 每一方都可以使用它来跟踪他们最后一次从另一端收到的东西,然后就可以如果数据包之间的时间过长,请关闭连接。

请注意,这假设您使用TCP/IP。如果你使用的是UDP,那么这是一个完整的其他水壶,因为它是无连接的。

1

好吧,我不知道你的程序是干什么的,所以也许这不可行,但我建议你避免试图始终保持套接字打开。只有在你使用它时才应该打开,当你不使用时应该关闭。

如果您在等待用户输入的读写之间,请关闭套接字。设计你的客户端/服务器协议(假设你正在做这个事情,而不是使用任何标准的协议,如http和/或SOAP)来处理这个问题。

如果连接断开,套接字将会出错;编写程序时,在写入套接字的过程中,如果出现此类错误,则不会丢失任何信息,并且在从套接字读取过程中发生错误时不会获取任何信息。事务性和原子性应该被放入你的客户/服务器协议中(再次假设你自己设计它)。

+0

关闭和重新打开套接字的优势是什么? – 2009-01-30 15:56:52

1

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

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

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

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

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

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

如果客户端不需要在过去一分钟内发送查询,就可以更简单地关闭连接。由于所有操作都是由客户端启动的,因此如果需要执行新操作,它总是可以打开一个新连接。它减少到仅仅这一点:

  1. 的服务器关闭,如果它没有在两分钟内接收到查询的连接。

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

但是,这并不能保证客户端服务器存在并随时可以接受查询。如果你需要这个功能,你将不得不实现一个“你在那里”,“是的,我是”你的协议中的查询/响应。

相关问题