java - 为什么 Java ServerSocket accept() 返回一个与 ServerSocket 具有相同端口的套​​接字?

标签 java sockets tcp serversocket

在服务器端,我使用这段代码:

ServerSocket server = new ServerSocket(1234);
Socket server_socket = server.accept();

我发现服务器正在监听 1234 端口。

当连接一个或多个客户端套接字时,它们都使用同一个端口 1234!

这真是令人困惑:

enter image description here

我记得多套接字不能使用同一个端口,对吗?谢谢。

最佳答案

TCP 连接由四个数字标识:

  • 客户端(或对端 1)IP
  • 服务器(或对端 2)IP
  • 客户端端口
  • 服务器端口

一个典型的TCP连接打开方式如下:

  • 客户端 IP 由客户端的 ISP 或 NAT 提供。
  • 服务器 IP 由用户提供或在 DNS 中查找。
  • 客户端从未分配的范围内任意选择一个端口(同时避免重复的四元组)
  • 服务器端口由协议(protocol)指定或明确指定。

您在 ServerSocket 中指定的端口是客户端连接的端口。它只不过是操作系统知道属于您的应用程序的端口号,以及将事件从操作系统传递到您的应用程序的对象。

ServerSocket#accept 方法返回一个Socket。 Socket 是包装单个 TCP 连接的对象。即客户端 IP、服务器 IP、客户端 TCP 端口和服务器 TCP 端口(以及一些传递相关数据的方法)

客户端发送的第一个 TCP 数据包必须包含您的应用监听的服务器端口,否则操作系统将不知道该连接属于哪个应用。

此外,没有动机将服务器 TCP 端口切换到另一个号码。它对服务器机器或客户端机器没有帮助,它需要一些开销来执行(您需要同时发送新旧 TCP 端口),并且还有额外的开销,因为服务器操作系统无法再通过以下方式识别应用程序单个端口 - 它需要将应用程序与其使用的所有服务器端口相关联(客户端仍然需要这样做,但典型的客户端比典型的服务器连接更少)


所见即所得

  • 两个入站连接,属于服务器(本地端口:1234)。每个服务器应用程序中都有自己的 Socket
  • 两个出站连接,属于客户端(远程端口:1234)。每个在客户端应用程序中都有自己的 Socket
  • 一个监听连接,属于服务器。这对应于接受连接的单个 ServerSocket

由于它们是环回连接,您可以在一台机器上看到两个端点混合在一起。您还可以在本地端和远程端看到两个不同的客户端端口(52506 和 52511)。

关于java - 为什么 Java ServerSocket accept() 返回一个与 ServerSocket 具有相同端口的套​​接字?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14091822/

相关文章:

networking - 为什么TCP在接收方缓冲数据

c++ - 如何处理 Perl TCP 套接字中的消息碎片?

java - 在 java 中使用谷歌的 gson 解析 JSON 输出

java - Graphics2D - 在所有平台上呈现相同的文本

java - KafkaProducer 未成功将消息发送到队列中

java - 无法使用Java下载数据文件

java - 安卓服务器: why it times out incoming connections randomly?

python - 如何使用Mininet Python API将UDP数据包从一台主机发送到另一台主机?

java - 如何让多个Android AsyncTask同时运行?

java - 如何识别NAT后面的Server Socket端口