Linux 如何重现静默断开的 TCP/IP 连接?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6116382/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 04:14:33  来源:igfitidea点击:

How to reproduce a silently dropped TCP/IP connection?

javalinuxnetworkingtcp

提问by Thorbj?rn Ravn Andersen

I have a situation where a Java program establishes a long-running TCP/IP connection to a server and said connection is functioning exactly as documented, except for one thing in an environment outside my control.

我有一种情况,Java 程序与服务器建立了长期运行的 TCP/IP 连接,并且所述连接的功能与文档完全一致,除了我无法控制的环境中的一件事。

Every Saturday that server is rebooted, but for some reason this is not communicated properly to my client so the connection just hangs waiting for a response for ever and ever. This is exactly the same behaviour seen with stale JDBC-connections, where some router in between server and client has found the connection to be idle and dropped it without notification.

每个星期六该服务器都会重新启动,但由于某种原因,这无法正确传达给我的客户端,因此连接只是挂起,永远等待响应。这与陈旧的 JDBC 连接所看到的行为完全相同,其中服务器和客户端之间的某些路由器发现连接空闲并在没有通知的情况下将其丢弃。

I need to be able to reproduce this scenario to be able to create a proper fix.

我需要能够重现此场景才能创建正确的修复程序。

Hence I need to know if there is a good way to simulate a router silently dropping connections under my control?

因此,我需要知道是否有一种好方法可以模拟路由器在我的控制下静默断开连接?

I can put a Linux box or a Mac between my development environment and the server. I can run the JVM in a virtual machine (vmware player) if I can do the dropping there.

我可以在我的开发环境和服务器之间放置一个 Linux 机器或 Mac。如果可以的话,我可以在虚拟机(vmware 播放器)中运行 JVM。

Suggestions are very welcome.

非常欢迎提出建议。



EDIT 2012-12-18: The solution that worked for me was to use a Java-based SOCKS5-proxy locally which could be suspended with Ctrl-Z at will, and tell my application to go through it.

编辑 2012-12-18:对我有用的解决方案是在本地使用基于 Java 的 SOCKS5 代理,它可以随意使用 Ctrl-Z 暂停,并告诉我的应用程序通过它。

采纳答案by HaveAGuess

Use Socatto forward your connection (it's very easy to set up as a TCP forwarder/proxy) even on the same machine if you want (by introducing a new port for the proxy to operate on and pointing it to the 'official' endpoint)

如果您愿意,甚至可以在同一台机器上使用Socat转发您的连接(设置为 TCP 转发器/代理非常容易)(通过引入一个新端口供代理操作并将其指向“官方”端点)

Check out the simple TCP forwarderexample

查看简单的 TCP 转发器示例

Then when you want to test outages you can either kill it (and the socket will be closed) or potentially try stopping the process (CTRL Z linux) to see how your destination handles stalled connections.

然后,当您想测试中断时,您可以终止它(并且套接字将关闭)或可能尝试停止该进程(CTRL Z linux)以查看您的目标如何处理停滞的连接。

Any questions? I'll try to answer... Good luck!

任何问题?我会尽量回答...祝你好运!

回答by Erick Robertson

Unplug the network cable from your computer.

从计算机上拔下网络电缆。

Bring up a simple test of just this module. Connect to the server and get to the waiting part. Then, pull out your network plug.

对这个模块进行一个简单的测试。连接到服务器并进入等待部分。然后,拔出网络插头。

It's important, of course, that you isolate this module and bring up only this module when you run this test. There may be other aspects of your program that require network access, and these should not be running.

当然,重要的是隔离此模块并在运行此测试时仅启动此模块。您的程序的其他方面可能需要网络访问,这些方面不应运行。

回答by hallsa

You should be able to temporarily apply a rule using iptables to drop all packets coming from the remote server (a.b.c.d). Something along the lines of :

您应该能够使用 iptables 临时应用规则来丢弃来自远程服务器 (abcd) 的所有数据包。类似的东西:

iptables -A INPUT -s a.b.c.d -j DROP

When you want to turn the filter off

当您想关闭过滤器时

iptables -D INPUT -s a.b.c.d -j DROP

You can play with those rules to drop other specific packets as well, but I think this will accurately model what your client software would see if the server simply disappeared.

您也可以使用这些规则来丢弃其他特定数据包,但我认为这将准确模拟您的客户端软件在服务器消失时会看到的内容。

Note though, that when you turn the connection back on, the remote server may still have the old connection alive, so this won't perfectly simulate a reboot.

但请注意,当您重新打开连接时,远程服务器可能仍具有活动的旧连接,因此这不会完全模拟重新启动。

回答by Malt

A native Linux based solution is to use tcwith netem. Netem is a special queue that can be attached to various network interfaces to cause delay, reordering and loss (see the web page for details). Some examples of netem use include:

基于本机 Linux 的解决方案是将tcnetem一起使用。Netem 是一个特殊的队列,可以附加到各种网络接口上,导致延迟、重新排序和丢失(详见网页)。netem 使用的一些示例包括:

tc qdisc change dev eth0 root netem loss 0.1%

To make eth0 drop 0.1% of all outgoing packets, and

使 eth0 丢弃 0.1% 的所有传出数据包,以及

tc qdisc change dev eth0 root netem loss 0.3% 25%

To create bursts of packet loss:

要创建数据包丢失突发:

This will cause 0.3% of packets to be lost, and each successive probability depends by a quarter on the last one.

这将导致 0.3% 的数据包丢失,并且每个连续概率取决于最后一个的四分之一。

If you need to drop incoming packets as well, you can use the ifb(Intermediate Functional Block device). You set it up, forward all packets received by eth0 to the ifb, and attach netem to the ifb to create loss or delay. See ifb's documentation for more details.

如果您还需要丢弃传入的数据包,您可以使用ifb(中间功能块设备)。您设置它,将 eth0 收到的所有数据包转发到 ifb,并将 netem 附加到 ifb 以创建丢失或延迟。有关更多详细信息,请参阅 ifb 的文档。