如何模拟强制关闭的 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 连接

使用网络面板进行分析时强制 Chrome 关闭/重新打开所有 TCP/TLS 连接

如何关闭一个TCP连接

怎样强制断开TCP连接

如何强制打开mpi 3使用TCP?

超时连接后如何关闭TCP连接?