ChatGPT解决这个技术问题 Extra ChatGPT

人为创建连接超时错误

当我收到连接超时时,我们的软件中出现了一个错误。这些错误非常罕见(通常是当我的连接被我们的内部网络断开时)。我怎样才能人为地产生这种效果,以便我可以测试我们的软件?

如果重要的话,应用程序是使用 CAsyncSocket 类在 C++/MFC 中编写的。

编辑:

我尝试使用不存在的主机,但出现套接字错误:

WSAEINVAL (10022) 参数无效

我的下一个尝试是使用 Alexander 的连接到不同端口的建议,例如 81(虽然在我自己的服务器上)。那效果很好。与断开连接完全相同(等待 60 秒,然后出错)。谢谢!

嗨,马克,我尝试了适合您的解决方案,但我收到的是 #503(服务不可用。)。不应该是其中之一,#504(网关超时)、#599(网络连接超时错误)、#598(网络读取超时错误)。
您想要连接超时还是读取超时?

e
emu

连接到不可路由的 IP 地址,例如 10.255.255.1。


同上,我想这是一个更好的答案,因为 google.com:81 可能有一天会到达。
...并且因为从您的单元测试中向其他人的服务器发送随机数据包是不礼貌的。
这并不总是有效。例如,对于 Python 的 urllib,这将返回“无路由到主机”异常。供参考
10.0.0.0 , 10.255.255.255, 172.16.0.0, 172.31.255.255, 192.168.0.0 ,192.168.255.255 所有这些都是不可路由的。
@FHI 提到的“No route to host”错误通常出现在两种情况下:(a)当您尝试连接到本地 LAN 中不可访问的主机时(意思是,它不回答 ARP 查询,所以它基本上是一个“ ARP 超时”)。 (b) 当路由器返回相应的 ICMP 错误时。如果您与测试的私有 IP 位于同一子网中,则会发生第一种情况。第二种情况,如果路由器不知道如何将您的数据包路由到其目的地,但在某些情况下,它们只是丢弃数据包而不发送 ICMP 错误。
A
Alexander

连接到现有主机,但连接到被防火墙阻止的端口,该端口仅丢弃 TCP SYN 数据包。例如,www.google.com:81。


这个答案很简单,就像下面@emu 的答案一样。我知道这个答案并不打算建议使用 google.com:81 但这里的重点是使用被阻止的不同端口。因此,您始终可以使用 :
除非它是您自己的服务器,否则访问其他服务器进行测试是不礼貌的。使用像下面提到的一个 emu 这样的文明解决方案,通过点击 10.255.255.1 等不可路由的 IP 地址,或设置您自己的虚拟服务器进行测试。
我认为谷歌可能已经封锁了这个端口。当我使用 Chrome 进行测试时,我只是“服务器不可用”。当我在下面使用@emu 的技巧时,连接按预期挂起。我错过了什么吗?
这将给出一个连接被拒绝而不是超时。
我同意@zeeshan,我们生活在一个文明的世界里,我们需要扼杀自己的服务器,而不是扼杀别人的服务器。
D
Der_Meister

很多好的答案,但最干净的解决方案似乎是this service

https://httpstat.us/504?sleep=60000

您可以配置超时持续时间(最长 230 秒)和最终返回码。


这正是我想要的。很棒的服务,会把它添加到我的书签中
T
Tom Chamberlain

如果您在 unix 机器上,您可以使用 netcat 启动端口侦听:

nc -l 8099

然后,修改您的服务以调用它通常对该端口执行的任何操作,例如 http://localhost:8099/some/sort/of/endpoint

然后,您的服务将打开连接并写入数据,但永远不会得到响应,因此会给您一个 Read Time Out(而不是 Connection Refused)


它很有用,因为您可以看到您的应用程序正在推送的任何数据。您可以检查您的应用程序是否要求回复。
如前所述,这对于导航到某种端点是正确的,但是如果我尝试以其他方式连接它会很快拒绝连接,这不是我现在试图模拟的行为。
@AlanSE - 你还有什么意思?端口号后面可以有任何内容; netcat 不在乎,因为它无法处理任何 URL
@TomChamberlain 哦等等,我可能知道我做错了什么。我正在尝试模拟 ssh 连接超时。所以我给它 localhost,端口 8099,但以前我没有给用户名,所以如果我只是输入一些 ssh alanse@localhost -p 8099,看起来就可以了。
要在套接字级别测试连接超时,请使用 kill -STOP <pid> 冻结 nc 进程(或直接 CTRL-Z 而不将其置于后台)。系统将像服务器正在运行一样,但等待服务器接受连接,导致连接超时(errno 110)。
s
speedplane

以下 URL 总是给出超时,并结合了上面 @Alexander 和 @Emu 的最佳答案:

http://example.com:81

使用 example.com:81 是对 Alexander 答案的改进,因为 example.com 是由 DNS 标准保留的,因此它始终无法访问,这与 google.com:81 不同,如果 Google 愿意,它可能会改变。此外,由于 example.com 被定义为不可访问,因此您不会淹没 Google 的服务器。

我会说这是对@emu 答案的改进,因为它更容易记住。


目前我看到 example.com 解析为 93.184.216.34,并且实际上提供了一个简短的 HTML 来解释它是一个示例域......端口 81 仍然没有响应。
问题实际上是 example.com 是否应该以这种方式使用。只有当他们正式让测试数据包泛滥成灾时,这个域才比任何其他商业域更好。未经许可将域用于此类目的是不道德的,至少可以说,即使不是非法的,因为处理这些数据包需要花钱。正如@AndyTheEntity 在他的回答中指出的那样,考虑使用httpstat.us
@Manuel您没有抓住重点... example.com 不是商业域名,它是为数不多的明确指定为不可用的域名之一。没有人可以拥有 example.com,并且 DNS 路由器知道它永远不会路由到真实地址。所以它不会花费任何人的服务器时间,使用它没有任何问题
@speedplane IANA 根据规定拥有该域并维护一个 Web 服务器,该服务器提供一个解释 example.com 用途的网页。域背后有基础设施,因此每个请求都会花费 IANA 资金。 RFC 2606 和 RFC 6761 中引用了允许的使用,您不能随意将域用于您喜欢的任何目的,例如 flodding 它们而不是另一个服务器,正如您所提到的。您声称 example.com is defined to be unreachable 不正确,它是可访问的。 81 端口现在无法访问,但是在哪里定义了将来可以保证的呢?
您指向的 RFC 专门允许进行 DNS 测试。他们建议您使用 .test 顶级域,而不是 example.com,但这些域显然是为此目的而设置的。是的,这可能会花费 IANA 一些钱,但这是他们提供的服务。我们的 DNS 费用正在为此付出代价。
W
Wai Ha Lee

10.0.0.0

10.255.255.255

172.16.0.0

172.31.255.255

192.168.0.0

192.168.255.255

所有这些都是不可路由的。


(正如我对已接受的答案所评论的那样)当我在 Node.js 中测试 XMLHttpRequest 时,与 10.0.0.010.255.255.255 的连接会触发 EACCES 错误而不是超时。但是,10.255.255.1172.16.0.0172.31.255.255192.168.0.0192.168.255.255 确实超时。
@JamieBirch 测试时您是否在网络 10.0.0.0/8 内?或者您的路由器知道这样的网络,或者是因为它直接连接到它,或者有一个禁止路由到它的策略?在所有这些情况下,您都会得到一个明确的错误,并且没有超时。
如果您的代码库出于安全原因阻止它们,这些可能不可行,因为它们是专用网络、环回地址。 en.wikipedia.org/wiki/Private_network webopedia.com/TERM/A/APIPA.html
192.168.0.0 给了我 ENETUNREACH,而不是超时。
H
Henrik Heimbuerger

您可以使用 Python REPL 在接收数据时模拟超时(即在成功建立连接之后)。只需要标准的 Python 安装即可。

Python 2.7.4 (default, Apr  6 2013, 19:54:46) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import socket
>>> s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)        
>>> s.bind(('localhost', 9000))
>>> s.listen(0)
>>> (clientsocket, address) = s.accept()

现在它等待传入的连接。将您要测试的任何内容连接到 localhost:9000。当您这样做时,Python 将接受连接并且 accept() 将返回它。除非您通过 clientsocket 发送任何数据,否则调用方的套接字应该在下一个 recv() 期间超时。


对我不起作用;有什么东西不见了。可能是 s.accept() 之前的 s.listen(5)
@bmaupin 这听起来很合理,我想我只是忘记了。现在编辑它(但是积压队列为 0),谢谢!
我能够将监听和接受部分放在一个 while True: 循环中,这似乎是一个很好的持久超时目标来进行测试。
它有效,但它给出“读取超时”错误,这与“连接超时”不同
除非您设置超时,否则它不会超时,而您没有。
z
zb226

我想提醒大家注意mitmproxy

使用 200:b@100:dr 的配置(取自他们的示例),您将获得一个随机断开的连接。


与超时不同
我想指出@zb226 的编辑在这种情况下并没有真正的帮助。虽然 pathod(我七年前推荐的)现在确实是 mitmproxy 的一部分,但这篇文章目前的形式毫无意义。我找不到关于如何使用 mitmproxy 实现类似事情的文档,所以我将把这条评论留给任何想知道它应该如何工作的人。
@amenthes 好吧,至少它让你意识到了这个事实:)
s
stoneboy

软件解决方案怎么样:

在应用服务器上安装 SSH 服务器。然后,使用套接字隧道在您的本地端口和应用程序服务器上的远程端口之间创建一个链接。您可以使用 ssh 客户端工具来执行此操作。让您的客户端应用程序连接到映射的本地端口。然后,您可以随意打破套接字隧道以模拟连接超时。


这不会导致连接超时,它会导致重置。
R
RoHS4U

如果您想使用活动连接,您也可以使用 http://httpbin.org/delay/#,其中 # 是您希望他们的服务器在发送响应之前等待的时间。只要您的超时时间短于延迟...应该模拟效果。我已经成功地将它与 python requests 包一起使用。

如果您发送任何敏感信息,您可能需要修改您的请求 - 不知道发送给他们的数据会发生什么。


最多 10 秒(如果您输入更高的数字,它将在 10 秒后响应)
T
Timothy Moody

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

例如,如果您想测试一个需要 15 秒才能响应的请求,您只需向 macgyver API 发出一个 post 请求。

JSON有效负载:

{
    "timeout_length": 15000
}

API 响应(15 秒后):

{
    "response": "ok"
}

macgyver 上的服务器超时程序
https://askmacgyver.com/explore/program/server-timeout/3U4s6g6u


M
Marcin Gil

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


佚名

尽管尚不完全清楚 OP 想要测试哪一个:尝试连接到不存在的主机/端口与已建立连接的超时之间是有区别的。我会和 Rob 一起去,等到连接正常,然后拉电缆。或者 - 为方便起见 - 将虚拟机用作测试服务器(使用桥接网络),并在建立连接后停用虚拟网络接口。


j
jdi

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

ssh -L 12345:realserver.com:80 localhost

这会将 localhost:12345 上的流量转发到 realserver.com:80 如果需要,您也可以在自己的本地计算机上循环它:

ssh -L 12345:localhost:8080 localhost

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


连接丢失不是超时。
@user207421 这取决于应用程序及其感知。如果应用程序已经建立了连接,然后您停止隧道,如果客户端没有收到正确的关闭,那么它可能会继续等待请求,直到达到超时。
R
Rob

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

拔出网络电缆 关闭您的机器和“目标”机器之间的开关(理想情况下,计算机插入的开关仍处于通电状态,以便机器保持其“网络连接”) 在目标机器上运行防火墙软件,静默丢弃接收到的数据

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


M
Matthew Scharley

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


M
Matt Howells

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

然而,为了对您的异常处理代码进行单元测试,也许您应该考虑抽象您的网络连接代码,并编写一个按需抛出异常的存根、模拟或装饰器。然后,您将能够测试应用程序错误处理逻辑,而无需实际使用网络。


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

我遇到了与您相同的问题。为了测试软件的行为,我只是在适当的时候拔掉了网线。在我想拔掉电缆之前,我必须设置一个断点。

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

如果物理断开导致不同的行为,您可以将计算机连接到便宜的集线器,并将上面提到的交换机放在集线器和主网络之间。

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


I
Ivan Marjanovic

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

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


D
Dmitry Khalatov

您可以尝试通过外部可能无法使用的端口(例如 200)连接到知名网站之一。大多数防火墙都在 DROP 模式下工作,它会为您模拟超时。


G
GHad

将您的网络电缆插入没有其他连接/电缆的交换机。恕我直言,这应该有效。


关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅