1

我希望我的问题的答案是指向文档的指针。但是,如果合适的话,我可以发布代码以寻找错误。

为了简化在家工作,我试图在单个 Wintel 操作系统/计算机中模拟将在微控制器中运行的服务器与将在 Wintel PC 中运行的 Java 客户端之间的交互。如果仿真足够好,我就不必将微控制器设备带回家只是为关系的 PC 端开发软件。

因此,在单个 Wintel 计算机(在家)中的单个 JVM 中,我这样做了:

  1. 创建了一个绑定到 192.168.1.63:3456(本地地址和本地(众所周知)端口)的新 ServerSocket 对象,并将 backlog 参数设置为 0。此对象表示通常在微控制器中的代码。
  2. 创建了一个绑定到 192.168.1.63:3456 和 192.168.1.63:0 的新(客户端)Socket 对象(远程地址、远程端口、本地地址、本地端口(临时端口的占位符))。该对象表示通常在 Wintel 计算机中的代码/对象。

我希望在上面第 2 项中创建的新 Socket 会阻塞(不连接),直到我调用 ServerSocket 的 accept() 方法。相反,Socket 创建尝试(以及 Socket 的隐式连接尝试)立即产生了一个新的(客户端)Socket 对象;我的(客户端)代码继续执行(接下来的几条指令是 .setReuseAddress(true)、.getInputStream()、.getOutputStream() 等)。

我在 Java API 文档中读到的所有内容都明确或隐含地表明,ServerSocket 的 accept() 调用允许 Sockets 完成连接到 ServerSocket 的过程(实际上是到 ServerSocket 创建的新 Socket ......);但是在 ServerSocket accept() 调用之前,我的 Socket 已经参加了比赛。

谁能指出我所看到的解释(客户端的连接尝试在服务器的 accept() 之前完成)?

希望这个解释能让我知道如何创建一个适当的模拟(不需要特殊代码,因为客户端和服务器都在一台计算机上)。

PS:以防万一......当我看到这种行为(上图)时运行的代码是单线程的。在有人指出它必须成为多线程才能完全成功之前;我知道。无论如何,我没想到我上面描述的。

4

1 回答 1

3

积压参数为 0

平台将向上或向下调整。请参阅 Javadoc。最小积压值从未低于 5,现在在某些平台上为 50 甚至 500。

我在 Java API 文档中阅读的所有内容都明确或隐含地表明,ServerSocket accept() 调用是允许 Socket 完成连接到 ServerSocket 的过程的原因

一切如什么?请提供引用。我不知道任何地方有任何文件证明这种错误信念是正当的。返回的套接字accept()表示从客户端的角度来看可能已经完全形成的连接。这就是积压队列的用途。

(实际上是 ServerSocket 创建的新 Socket...);但是在 ServerSocket accept() 调用之前,我的 Socket 已经参加了比赛。

您的连接由 TCP 堆栈完成并放置在积压队列中。所做的accept()只是创建本地套接字作为其端点,甚至可能没有。

这都是正常的。你的期望是不正确的。

如果它“弄乱了他们俩”,那么您的代码中就有错误。客户端完成连接并发送请求并在服务器调用之前等待回复是完全正常的accept().

于 2015-02-18T21:27:14.167 回答