2010-10-22 165 views
0

系统背景: 它基本上是一个客户端/服务器应用程序。服务器是嵌入式设备,客户端是用C++开发的Windows应用程序。套接字重新连接失败

问题:在运行了大约一周后,客户端/服务器之间的通信断开,
因为这样服务器无法连接回客户端并需要重新启动才能恢复。看起来像系统正在遇到套接字重新连接问题。此外,网络有时会经历间歇性故障。在远端

  • 端口

    1. 突然终止锁定

    想如何清理插座或关机干净,以便重新连接正常情况提出了一些建议。其他替代方案?

    感谢, 侯赛因

  • +0

    祝你好运,如果你得到的回应! – Chubsdad 2010-10-22 10:51:43

    +0

    通常,它是连接到服务器的客户端,而不是其他方式。简单地关闭现有套接字并打开另一个套接字有什么问题? – Dialecticus 2010-10-22 11:04:06

    +0

    @Dialecticus - 没有什么,提供这种情况下的逻辑是正确的。虽然很难获得100%的权利。 – 2010-10-22 11:12:24

    回答

    2

    它听起来并不像你是在一个位置,很容易地编写压力测试应用程序更迅速带外的复制本,这是我通常建议。务实的解决方案可能是在您认为系统最忙或出现问题时定期重新启动服务器和客户端。这听起来像是作弊,但我参与的许多生产系统都采用这种方法来最大化系统正常运行时间。

    我的首选解决方案是抽象服务器和客户端套接字代码(希望您的设计可以在不需要太多工作的情况下完成)并使用它来实现客户端和服务器测试应用程序,这些应用程序只能用于压力测试通过在短时间内模拟大量正常的套接字流量来实现套接字代码 - 这有助于识别随时间推移可能导致问题的时序窗口和边缘情况,并且可能加快获取可调试再现的过程 - 您可以模拟网络错误在您的测试代码中定期删除客户端或服务器上的套接字。

    进一步采取战略方面的一步是确保您在客户端和服务器端的套接字处理程序中具有良好的诊断功能。跟踪套接字的打开和关闭,特别关注您的套接字错误并重新连接路径,因为您知道网络不可靠。确保日志以时间戳顺序输出。像这样简单的事情可能会很快显示出什么错误或情况会引发您的问题。您可以使用上面提到的测试应用程序快速确保日志正确并完整。

    你可能想要检查的一件事是你没有被重用地址的能力缺乏打击。有时,当套接字被关闭时,它不能立即重新用于重新连接尝试,因为在一端或另一端仍有剩余活动。您可以通过在您的套接字上尝试使用SO_REUSEADDR和SO_LINGER来解决此问题(基于我的Windows/Winsock体验)。不过,我的第一个重点是确保客户端和服务器上的套接字代码正确处理所有错误和主线情况,然后再担心这一点。

    1

    一个常见问题是,当连接断开时,操作系统将以TIME_WAIT状态保持打开状态。如果您想重新启动服务器套接字,将无法直接重新打开相同的端口,因为它仍然存在于操作系统中。 为避免这种情况,您需要设置参数SO_REUSEADDR,以便操作系统允许您重新使用该端口(如果它处于服务器套接字的TIME_WAIT状态)。

    例子:

    int optval=1; 
    // set SO_REUSEADDR on a socket to true (1): 
    setsockopt(s1, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof optval); 
    
    0

    我遇到加密连接类似的东西。我相信在我的情况下,这是因为客户端在4分钟的FIN_WAIT期间内断开连接并重新连接。初始连接被回收(通过操作系统),服务器看不到退出。当客户端失去连接时,SSL身份验证会丢失,客户端会尝试重新进行身份验证。这是服务器认为会话中间的事情。然后服务器挂在客户端上。我认为服务器SSL代码认为这是一个人在中间攻击或只是感到困惑,并关闭连接。

    +0

    这都不是可能的。 FIN_WAIT时间段影响首先结束的结束,而不是首先结束结束的结束。由于传入的SYN以及新的TCP序列号,服务器会将其视为新的TCP连接。在SSL级别,SSL会话可以恢复。你的问题在别处。 – EJP 2010-10-23 02:00:39

    +0

    我认为你错了。我调试关闭客户端(一个Windows服务)并重新启动它。服务器从未收到连接关闭事件,并且相同的连接被重用。 – Jay 2010-10-25 14:09:54