我最近从Windows 8升级到Windows 8.1。在升级之后,我开始遇到与Java中的TCP套接字相关的问题。
我工作的应用程序使用Java ServerSocket
,另一个进程连接到该ServerSocket
以发送数据。非常标准的东西,已经在许多操作系统和Java版本中使用多年。
在Windows 8.1下,与这些read
的连接偶尔会被“卡住”。这似乎在某种程度上取决于一次通过套接字传输的数据量,但是当一次发送一个适度的~1 kB的数据时,它很容易发生。
当套接字“卡住”时,会发生以下情况:
InputStream
上调用InputStream.read
时,它永远不会得到“-1”指示符,表示已达到EOF。相反,该进程会在ServerSocket
调用中无限期阻止。netstat -b
的ESTABLISHED。如果发送数据的流程已终止(在这种情况下System
显示该连接与流程netstat
相关联,则情况甚至如此。SocketListener
不会继续显示已建立的套接字,但'接收'(Windows 8.1)计算机确实显示已建立的套接字连接。自升级到Windows 8.1以来,我没有注意到任何其他网络问题。在Windows 8上运行时,相同的代码正常工作,因此操作系统升级似乎是关键。我的环境细节:
Here is a Gist导致我环境问题的Java测试程序。必须先运行SocketTalker
。它将打印它已绑定的套接字。使用2个参数运行SocketListener
:运行SocketListener
的主机和SocketListener
绑定的端口。出现问题时,SocketListener
会报告新的套接字连接,并且通常会报告至少收到一些数据。但是,它不会报告套接字连接已关闭。
我认为{{1}}可能包含错误,但它模仿了在多个Java版本,JRE实现和操作系统中成功运行多年的产品中使用的代码。
任何在Windows中调试网络堆栈的技术都将受到赞赏。我不太喜欢Windows开发......
编辑:
Here is a Wireshark capture问题的一个示例。 192.168.1.26是运行SocketTalker的CentOS机器,而192.168.1.9是运行SocketListener的Win 8.1机器。看起来Windows框在收到数据后就停止响应。我可能已经停止了所有的说法和完成之前的捕获,但我认为我得到了关键部分。
答案 0 :(得分:0)
您的服务器端永远不会关闭已接受的套接字。这可能会导致任何不良行为,当然包括ESTABLISHED状态的持续存在。
但是,您的Wireshark跟踪清楚地显示了传入的FIN和传出的ACK,因此它似乎不是您描述的行为的实例。请注意,服务器没有传出的FIN,这证明了永远不会关闭接受的套接字的观点。
注意您的描述非常不准确。 ServerSocket
不参与I / O.连接位于客户端的Socket
和服务器的接受Socket
之间。