如何模拟强制关闭的 TCP 连接?
Posted
技术标签:
【中文标题】如何模拟强制关闭的 TCP 连接?【英文标题】:How to emulate a forcibly closed TCP connection? 【发布时间】:2012-03-29 12:51:04 【问题描述】:我的测试程序如何在它所连接的 TCP 侦听器中导致“连接被强制关闭”错误?
我的理解是我必须在不遵循 TCP 协议的情况下关闭连接,即不发送“FIN”数据包。这可以在 TCP 模式下使用标准 .NET Socket
完成吗?
我似乎可以通过打开几个连接然后终止测试程序来做到这一点,但我尝试过的任何其他方式都没有。
【问题讨论】:
【参考方案1】:我能够通过使用实用程序 CurrPorts 来完成此操作。
出于我的目的,我试图在第三方 SDK 中测试由该错误引起的崩溃。
在管理员模式下运行 CurrPorts 看到连接后点击刷新。 右键单击并“关闭选定的 TCP 连接”(或使用 ctl-T)【讨论】:
【参考方案2】:您应该不能够通过打开多个连接然后终止测试程序来实现此目的。当程序退出时,内核应该负责关闭所有的 TCP 连接(干净地,至少在 TCP 层及以下层)。
事实上,如果您可以从非特权用户空间执行任何操作来导致 TCP 连接挂起/断开,那是您的内核中的一个错误,应该修复 :-)
您最好的选择可能是使用原始套接字来注入您想要的任何数据包。您将必须在这些数据包上构建自己的 TCP 和 IP 标头,但出于单元测试的目的,您可以使用大多数固定值和一些变量值来构建标头。建议从正常工作的数据包捕获开始会话,在正确的位置添加一个 RST 数据包,然后在您的测试程序中或多或少地播放该序列。
我确实认为这样做来测试您的应用程序是矫枉过正的。您主要使用这种方法测试主机的 TCP 堆栈。要测试您的应用程序,模拟套接字以使其在正确的时间返回错误可能就足够了。
【讨论】:
嗯...你说的很有道理,但同时,只要谷歌搜索“强制关闭”,你就会看到这个错误出现的频率(一直)。此外,如果电缆被猛拉或 ISP 处的灯熄灭或类似的事情,肯定也会发生这种情况。我们的应用程序不能在这种情况下崩溃和烧毁;它需要优雅地恢复。 当然,这可能发生在网络故障、数据包丢失、电缆被拉断、操作系统错误、路由器故障、内核崩溃以及其他一百种情况下。但是您的主机 TCP 堆栈不会让用户空间软件故意导致它。但是您应该能够通过模拟套接字来充分测试您的应用程序,正如Jens H 所解释的那样,比我所做的更详细。【参考方案3】:根据您的代码环境,我看到了几种可能性。
一种方法是实现Adapter pattern,如此处的 SO 问题所述:TDD and Mocking out TcpClient。 (参见那里的代码示例。)
您可以实现一个包装器类,该包装器类本身使用 TcpClient 和 mock 包装器类的接口。这样做可以将您与 TcpClient 分离,并在需要时更改为其他实现或协议。
第二个想法是使用像 Moq、RhinoMock(都是开源的)这样的模拟框架或像 Telerik 的 JustMock(我个人偏好)这样的商业框架。 JustMock 还提供了一个非常适合此任务的免费版本,也可用于商业项目。使用这样的框架,您可以轻松地模拟出网络类的公共接口。
当然,第一个选项也可以使用模拟框架。
无论哪种方式,然后可以安排模拟以引发所需的异常并测试您的代码如何处理它。
【讨论】:
【参考方案4】:您可以从 Microsoft 网站下载 tcp 监控工具。 util 名称是 TcpView,可让您监控和关闭您的 tcp 连接以模拟这种情况。
TcpView:
https://technet.microsoft.com/en-us/sysinternals/tcpview.aspx
【讨论】:
以上是关于如何模拟强制关闭的 TCP 连接?的主要内容,如果未能解决你的问题,请参考以下文章
ShipModul 的 Miniplex-3Wi 强制关闭 TCP 连接