我遇到这样一种情况:Java程序与服务器建立了长时间运行的TCP / IP连接,并且所述连接的运行完全符合记录,除了我控制之外的环境中的一件事。
每个星期六该服务器都重新启动,但由于某种原因,这不能正确地传达给我的客户端,因此连接只是挂起等待永远和永远的响应。这与过时的JDBC连接完全相同,其中服务器和客户端之间的某些路由器发现连接处于空闲状态并且在没有通知的情况下将其丢弃。
我需要能够重现此方案才能创建正确的修复程序。
因此,我需要知道是否有一种很好的方法来模拟路由器静默地丢弃我控制下的连接?
我可以在我的开发环境和服务器之间放置一个Linux机器或Mac。我可以在虚拟机(vmware播放器)中运行JVM,如果我可以在那里进行删除。
建议非常欢迎。
编辑2012-12-18:对我有用的解决方案是在本地使用基于Java的SOCKS5代理,可以随意使用Ctrl-Z暂停,并告诉我的应用程序完成它。
答案 0 :(得分:9)
使用Socat转发您的连接(很容易设置为TCP转发器/代理),即使在同一台机器上也是如此(通过为代理引入一个新端口来操作并指向它)到'官方'终点)
然后,当您想要测试中断时,您可以终止它(并且套接字将被关闭)或者可能尝试停止进程(CTRL Z linux)以查看目标如何处理停滞的连接。
有任何问题吗?我会试着回答......祝你好运!
答案 1 :(得分:9)
您应该能够使用iptables临时应用规则来丢弃来自远程服务器的所有数据包(a.b.c.d)。有点像:
iptables -A INPUT -s a.b.c.d -j DROP
如果要关闭过滤器
iptables -D INPUT -s a.b.c.d -j DROP
您可以使用这些规则来删除其他特定数据包,但我认为这将准确地模拟客户端软件在服务器消失后会看到的内容。
但请注意,当您重新打开连接时,远程服务器可能仍然保持旧连接,因此这不能完美地模拟重新启动。
答案 2 :(得分:3)
从计算机上拔下网线。
对这个模块进行简单的测试。连接到服务器并进入等待部分。然后,拔出网络插头。
当然,当您运行此测试时,隔离此模块并仅显示此模块非常重要。您的程序可能还有其他方面需要网络访问,而这些方面不应该运行。
答案 3 :(得分:1)
基于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的文档。