我最近从 Windows 8 升级到了 Windows 8.1。升级后,我开始遇到与 Java 中的 TCP 套接字相关的问题。
我工作的一个应用程序使用 Java ServerSocket
s,另一个进程连接到它以发送数据。多年来在许多操作系统和 Java 版本中运行的相当标准的东西。
在 Windows 8.1 下,与这些ServerSocket
s 的连接偶尔会“卡住”。这似乎在某种程度上取决于一次通过套接字传输的数据量,但是当一次发送适度的约 1 kB 数据时,它很容易发生。
当套接字“卡住”时,会发生以下情况:
- 发送端完成发送数据并关闭套接字,进程甚至可以终止。就它而言,数据似乎已经发送成功。
- 接收方通常会获取已发送的部分或全部数据。但是,当调用
read
套接字的InputStream
.InputStream.read
相反,进程在调用中无限期地阻塞。 - netstat 显示与
ServerSocket
. 即使发送数据的进程已终止,情况也是如此(在这种情况下netstat -b
,表明连接与 process 相关联System
。 - 我已经尝试在系统之间进行连接,但问题仍然存在。具体来说,我已经从 CentOS 虚拟机(由 Win 8.1 机器托管)连接到 Win 8.1 机器。在这种情况下,
netstat
“发送”(CentOS)机器不会继续显示已建立的套接字,但“接收”(Windows 8.1)机器确实显示已建立的套接字连接。 - 我尝试通过环回接口 (127.0.0.1) 和实际网络接口(通过指定我的外部可见 IP)进行连接,结果相同。
自从升级到 Windows 8.1 后,我没有注意到任何其他网络问题。在 Windows 8 上运行时,相同的代码可以正常工作,因此操作系统升级似乎是关键。我的环境的细节:
- Windows 8.1 专业版 64 位
- Oracle HotSpot 7u40 JRE(尽管我尝试使用 7u45 和 6u37,得到相同的结果)
- 戴尔灵越 5720
- 正在使用 Realtek PCIe FE(有线)网络适配器
这是在我的环境中导致问题的 Java 测试程序的要点。SocketListener
必须先运行。它将打印它已绑定到的套接字。使用 2 个参数运行SocketTalker
:正在运行的主机和绑定到SocketListener
的端口。SocketListener
当问题发生时,SocketListener
报告一个新的套接字连接,通常,它至少收到了一些数据。但是,它不会报告套接字连接已关闭。
我想它可能SocketListener
包含一个错误,但它模拟了在许多 Java 版本、JRE 实现和操作系统中成功运行多年的产品中使用的代码。
任何在 Windows 中调试网络堆栈的技术都将受到赞赏。我不是Windows开发人员...
编辑:
这是问题示例的 Wireshark 捕获。192.168.1.26 是运行 SocketTalker 的 CentOS 机器,而 192.168.1.9 是运行 SocketListener 的 Win 8.1 机器。看起来 Windows 框在收到数据后停止响应。我可能在一切都说完之前就停止了捕获,但我想我得到了关键部分。