如何重现一个默默丢弃的TCP / IP连接?

我有一种情况,一个Java程序build立一个长期运行的TCP / IP连接到一个服务器,并且所说的连接的function与文档完全一样,除了在我的控制之外的环境中的一件事。

每个星期六,服务器都重新启动,但由于某种原因,这不能正确传达给我的客户端,所以连接只是挂起来等待响应。 这与使用过时的JDBC连接看到的行为完全相同,在服务器和客户端之间的某个路由器发现连接处于空闲状态并在没有通知的情况下将其删除。

我需要能够重现这种情况能够创build一个适当的修复。

因此,我需要知道是否有一个很好的方法来模拟路由器在我的控制下默默地放下连接?

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

build议是非常受欢迎的。


编辑2012-12-18:为我工作的解决scheme是使用本地的基于Java的SOCKS5代理,可以用Ctrl-Z任意暂停,并告诉我的应用程序通过它。

Solutions Collecting From Web of "如何重现一个默默丢弃的TCP / IP连接?"

即使在同一台计算机上,使用Socat来转发您的连接(这很容易设置为TCP转发器/代理)(通过引入一个新的端口让代理进行操作并将其指向“官方”端点)

查看简单的TCP转发器示例

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

任何问题? 我会尽力回答…祝你好运!

您应该可以使用iptables临时应用规则,以删除来自远程服务器(abcd)的所有数据包。 有些东西是:

 iptables -A INPUT -s abcd -j DROP 

当你想关闭过滤器

 iptables -D INPUT -s abcd -j DROP 

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

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

从电脑拔下网线。

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

当然,当你运行这个测试时,你隔离这个模块并且调出这个模块是很重要的。 您的程序可能还有其他方面需要网络访问,而且这些方面不应该在运行。

原生的基于Linux的解决方案是使用tc和netem 。 Netem是一个特殊的队列,可以连接到各种网络接口,从而导致延迟,重新排序和丢失(请参阅网页了解详细信息)。 netem使用的一些例子包括:

 tc qdisc change dev eth0 root netem loss 0.1% 

使eth0下降0.1%的所有传出数据包,并

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

创建丢包的爆发:

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

如果您还需要丢弃传入数据包,则可以使用ifb (中级功能块设备)。 你把它设置好,把eth0收到的所有数据包都转发给ifb,并把netem连接到ifb上,造成丢失或延迟。 有关更多详细信息,请参阅ifb的文档。