在服务器端,我使用这段代码:
ServerSocket server = new ServerSocket(1234);
Socket server_socket = server.accept();
我发现服务器正在监听 1234 端口。
当连接一个或多个客户端套接字时,它们都使用同一个端口 1234!
这真是令人困惑:
我记得多套接字不能使用同一个端口,对吗?谢谢。
最佳答案
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/