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

为什么Java ServerSocket accept()返回与ServerSocket具有相同端口的套接字?,java,sockets,tcp,serversocket,Java,Sockets,Tcp,Serversocket,在服务器端,我使用以下代码: ServerSocket server = new ServerSocket(1234); Socket server_socket = server.accept(); 我发现服务器正在侦听端口1234 连接一个或多个客户端套接字时,它们都使用相同的端口1234 这确实令人困惑: 我记得多个套接字不能使用同一个端口,不是吗?谢谢。TCP连接由四个数字标识: 客户端(或对等1)IP 服务器(或对等2)IP 客户端端口 服务器端口 典型的TCP连接如下所示:

在服务器端,我使用以下代码:

ServerSocket server = new ServerSocket(1234);
Socket server_socket = server.accept();
我发现服务器正在侦听端口1234

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

这确实令人困惑:


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

TCP连接由四个数字标识:

  • 客户端(或对等1)IP
  • 服务器(或对等2)IP
  • 客户端端口
  • 服务器端口
典型的TCP连接如下所示:

  • 客户端IP由客户端的ISP或NAT提供
  • 服务器IP由用户提供或在DNS中查找
  • 客户端从未分配的范围内任意选择端口(同时避免重复的四个端口)
  • 服务器端口由协议或显式指定
您在ServerSocket中指定的端口是客户端连接到的端口。它只不过是操作系统知道的属于应用程序的端口号和将事件从操作系统传递到应用程序的对象

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

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

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


你看到的是

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

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

为什么不呢?请仔细阅读TCP的工作原理。您要寻找的简单答案是,您没有注意到右侧的侦听。它只有一个。不,.accept()不返回两个套接字。我调用了accept()两次,这里实际上有两个套接字,请看我的屏幕截图。@StefanosKalantzis accept在调用两次时返回两个套接字我的图片中的两个127.0.0.1.1234是同一个套接字吗?@MrROY它们不同
socket
s(请注意,另一个端口在每个端口中都不同)来自同一个
ServerSocket
谢谢!你是说来自同一个ServerSocket的这两个(或更多)套接字可以(或必须)使用吗是否使用相同的端口?@MrROY同一服务器套接字返回的套接字必须与服务器套接字具有相同的服务器端口,但是来自同一服务器套接字的两个套接字在客户端IP或客户端端口上总是不同的(除非服务器IP不同-您的服务器有两个不同的网卡,都面向同一个网络,或者您有一个假装为两个的网卡)