2009-11-01 173 views
2

我有一个应用程序处理多种Java套接字连接到不同种类的远程机器(某些PC,其他是嵌入式设备)。这些套接字和流不应该无限期关闭,除非有一个很好的原因(例如远程系统崩溃)。Java套接字流意外终止

我经常遇到,其中输入流意外结束,不需要任何理由(值是-1),即在远程机器并不表示一连接中止的问题。但是,当我放弃这些-1读取并继续从流中读取时,远程机器实际上稍后会发送新数据。这可能会持续很长时间。我也可以写入输出流。

在当前形势下,我有治疗-1作为流的末尾之间的选择和关闭套接字(误报),或忽略-1投入和风险尚未收到通知的真正断开的。

我一直没能创造这一问题的工作示例和出现的问题随机。

任何想法有什么不对?

修改为添加: Java端点是对现有VB应用程序的重写,没有这些问题(至少据我所知)。

+2

我认为在你的源代码中窥视会有所帮助。 – 2009-11-01 13:57:17

+1

谢谢,但正如我所说,我还没有创建一个简单的,工作的问题的例子,整个事情是太多的代码。 – 2009-11-01 14:36:23

+0

“太多代码”,可能是您的问题的一部分。它不应该那么复杂。 – 2009-11-01 16:03:27

回答

0

检查路由器是否正常。廉价路由器,特别是那些做NAT的人,通常会偶尔清理它们的连接表,导致连接失效。

在任何情况下,你的应用程序应该是对这些东西(他们会再次发生)强大的,你可能会不经商业价值跨线regularily发送数据包帮助它。

+0

我是。 “保持活着”消息被定义和使用,但没有帮助。 当我在同一台机器上运行服务器和客户端时,问题也出现了。 – 2009-11-01 13:43:40

+0

另外,正如我所说的,如果我忽略-1,它至少在几个小时内就像一个魅力。 – 2009-11-01 13:46:29

-1

您的环境中显然存在一些网络问题,您可以尝试跟踪它们,但暂时更安全关闭流并重新打开它。这就是API所承担的。

+0

'网络问题'不会导致'read()'返回-1。唯一可能导致的结果就是法定FIN分段的接收。 – EJP 2017-05-06 10:38:17

0

你有没有使用过Wireshark?它非常容易设置,并且可能会让你知道在发生这种情况时TCP会话是否有任何异常。

我有类似的东西,你的问题,曾经和我通过发送ping消息服务器和客户端之间的每一分钟解决它。 (后来事实证明,如果没有流量超过10分钟,防火墙问题偶尔会关闭一半的连接。)

我知道你在做KeepAlive消息,但它沿途的东西可能是不支持他们。如果您用几个字节发送自己的ping消息,则可以确定。在任何情况下,我都会使用Wireshark捕获两端的实际数据包,以确保KeepAlive消息确实能够一直通向终端。

+0

我没有发送tcp keepalive,它是Thorbjørn建议的实际“空白”业务消息,以确保至少每隔十分钟发送至少一条消息。较少是困难的,因为整个事情也需要在相当昂贵的3G移动网络上工作,所以我还需要保持低字节数。 – 2009-11-01 14:41:00

+0

啊,如果你发送真正的0字节的数据包从应用层到应用层,那么我估计不是这样。你可以用1分钟的频率试试它,即使这不是一个实际的产品解决方案。但是我也错过了你说在同一台机器上运行时发生了什么。我会尝试首先复制它。如果可能发生在同一台机器上,那么无需浪费时间使用wireshark和网络。 – 2009-11-01 15:04:28

1

如果你得到-1意味着流被关闭,那么你可以不读超出这一范围,寻找更多的数据。流关闭后,不能再次读取。

这听起来像你正在执行一个read()并将其转换为一个字节。这意味着你不能区分255值(你可以阅读的更多)和-1流的封闭值(你不能)

+1

我不会将stream.read()操作的结果转换为字节。我知道这些文档是怎么说的。如果我只是忽略-1并且在100毫秒后再次尝试读取,并且无限期地重复,则新数据最终到达。这很疯狂,但它确实有效。 – 2009-11-01 19:14:35

+0

这种行为可能是在套接字之上分层流的结果(在操作系统级提供自己的流语义)。但是,鉴于Bug Parade没有任何类似行为的报告,我会在怀疑Java之前怀疑OP的代码。 – kdgregory 2009-11-02 12:53:35