1

我最近从 Windows 8 升级到了 Windows 8.1。升级后,我开始遇到与 Java 中的 TCP 套接字相关的问题。

我工作的一个应用程序使用 Java ServerSockets,另一个进程连接到它以发送数据。多年来在许多操作系统和 Java 版本中运行的相当标准的东西。

在 Windows 8.1 下,与这些ServerSockets 的连接偶尔会“卡住”。这似乎在某种程度上取决于一次通过套接字传输的数据量,但是当一次发送适度的约 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 框在收到数据后停止响应。我可能在一切都说完之前就停止了捕获,但我想我得到了关键部分。

4

1 回答 1

0

您的服务器端永远不会关闭接受的套接字。这可能导致任何类型的不良行为,当然包括 ESTABLISHED 状态的持久性。

但是,您的 Wireshark 跟踪清楚地显示了传入的 FIN 和传出的 ACK,因此它似乎不是您描述的行为的实例。请注意,服务器没有传出 FIN,这证明了永远不会关闭接受的套接字的观点。

注意您的描述非常不准确。ServerSocket不参与 I/O 。连接Socket在客户端和服务器之间接受Socket

于 2013-10-23T04:08:44.583 回答