人工制造连接超时错误

394

我们的软件出现了一个bug,当我遇到连接超时时,它就会发生。这些错误非常罕见(通常是由于内部网络丢失连接)。我如何人为地产生这种效果以便测试我们的软件?

如果有关系的话,这个应用程序是使用C++/MFC编写的,使用CAsyncSocket类。

编辑:

我已经尝试过使用不存在的主机,但是我得到了套接字错误:

WSAEINVAL (10022) 无效的参数

我的下一步尝试是使用Alexander的建议连接到另一个端口,例如81(但是在我的自己的服务器上)。那很好用。正好和断开连接一样(等待60秒,然后报错)。谢谢!


嗨,马克,我尝试了你提供的解决方案,但我收到的是**#503(服务不可用)。难道不应该是其中之一,#504(网关超时)、#599(网络连接超时错误)、#598**(网络读取超时错误)吗? - CoDe
你想要连接超时还是读取超时? - user207421
22个回答

3

有一些可用的服务,可以通过调用API来人工创建原始超时,您可以在其中指定服务器响应所需的时间。macgyver上的服务器超时就是这样一个示例。

例如,如果您想测试需要15秒钟才能响应的请求,您只需向macgyver API发出POST请求即可。

JSON负载:

{
    "timeout_length": 15000
}

API响应(15秒后):

{
    "response": "ok"
}

在麦克盖弗上的服务器超时程序
https://askmacgyver.com/explore/program/server-timeout/3U4s6g6u

1

你可以安装Microsoft Loopback驱动程序,它将为您创建一个单独的接口。然后,您可以在其上连接到自己的某个服务(自己的主机)。然后,在网络连接中,您可以禁用/启用此类接口...


1

尽管不完全清楚OP想要测试哪一个:尝试连接不存在的主机/端口和已经建立连接的超时之间存在区别。我会像Rob一样等待连接工作,然后再拔掉电缆。或者 - 为了方便起见 - 可以使用虚拟机作为测试服务器(具有桥接网络),并在建立连接后仅停用虚拟网络接口。


1

另一个选项是建立一个本地端点,返回延迟响应。你可以用几行Python代码来实现:

from flask import Flask
from time import sleep

app = Flask(__name__)

@app.route('/delayed', methods = ['POST'])
def delayed_request():
    sleep(120) # delay response by 120 seconds
    return {"msg": "completed"}

app.run(port = 5000)

测试一下:

curl --request POST http://localhost:5000/delayed

请注意,这需要安装 Flask 作为依赖项(pip install flask)。

1

我经常用的模拟随机连接超时的技巧是使用ssh本地端口转发。

ssh -L 12345:realserver.com:80 localhost

这将把本地主机上的流量转发到realserver.com的80端口。如果您想要,您也可以在自己的本地机器上循环执行此操作:
ssh -L 12345:localhost:8080 localhost

所以你可以将应用程序指向本地主机和自定义端口,流量将被路由到目标主机:端口。然后您可以退出此 shell(退出后可能还需要按下 ctrl+c),它将终止转发,从而导致应用程序看到连接丢失。

1
连接丢失并不等同于超时。 - user207421
@user207421 这取决于应用程序及其感知。如果应用程序已经建立了连接,然后您停止隧道,如果客户端没有收到适当的关闭,则可能会一直等待请求,直到达到超时时间。 - jdi

0

对我而言最简单的方法是在公司路由器上添加基于目标网络的静态路由。只需将流量路由到一些无响应的主机(例如您的计算机),您就会获得请求超时。

对我来说最好的事情是,静态路由可以通过 Web 接口进行管理,并轻松启用/禁用。


0

我过去使用过几种策略来模拟网络问题:

  1. 拔掉网络电缆
  2. 关闭交换机(最好是保持计算机所连接的交换机仍然通电,以便计算机维持其“网络连接”)与“目标”计算机之间的交换机
  3. 在目标计算机上运行防火墙软件,静默丢弃接收到的数据

其中一个想法可能会为您提供一些人工生成所需场景的手段。


0

根据您安装/可用的防火墙软件,您应该能够阻止出站端口,根据防火墙的设置方式,它应该只会丢弃连接请求数据包。没有连接请求,就没有连接,超时发生。如果在路由器级别实现这一点,可能会更好(它们倾向于丢弃数据包而不是发送复位,或者等效情况),但肯定有一个软件包可以完成这个技巧。


0

我曾经遇到和你类似的问题。为了测试软件行为,我只需在适当的时间拔掉网络电缆。我必须在想要拔掉电缆之前设置一个断点。

如果我再做一次,我会在网络电缆中放置一个开关(通常是闭合的瞬时按钮型)。

如果物理断开引起不同的行为,您可以将计算机连接到一个廉价的集线器,并将上述开关放置在您的集线器和主网络之间。

--编辑-- 在许多情况下,您需要使网络连接工作直到程序达到某个特定点,然后使用提供的许多建议之一断开连接。


0

最简单的方法是使用CurrPorts断开连接。

然而,为了对异常处理代码进行单元测试,你应该考虑抽象出网络连接代码,并编写一个桩程序、模拟程序或装饰器,以便按需抛出异常。这样,你就能够测试应用程序的错误处理逻辑,而不必实际使用网络。


使用CurrPorts,我似乎只能关闭连接(这会导致下一个recv()立即失败),但找不到一种模拟超时的方法(即不再传输数据,但连接保持打开)。 - Henrik Heimbuerger
我很欣赏这个答案,因为它建议使用单元测试按需模拟连接异常。 - Danny Bullis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接