![](/img/trans.png)
[英]Why Java ServerSocket accept() returns a socket with the same port as ServerSocket?
[英]Does ServerSocket accept return socket on arbitrary port?
我在 java 中的 serversockets 方面看到了许多与此类似的答案:“假设您有一台服务器,在端口 5000 上有一个 serversocket。客户端 A 和客户端 B 将连接到我们的服务器。
客户端 A 在端口 5000 上向服务器发送请求。客户端 A 端的端口由操作系统选择。 通常,操作系统会选择下一个可用的端口。 此搜索的起点是先前使用的端口号 + 1(例如,如果操作系统最近发生在我们的端口 45546 上,则操作系统将尝试 45547)。
假设没有连接问题,服务器接收客户端 A 在端口 5000 上的连接请求。服务器然后打开自己的下一个可用端口,并将其发送给客户端。 在这里,客户端 A 连接到新端口,服务器现在可以再次使用端口 5000。”
我已经在关于 stackoverflow 的多个问题中看到了这样的答案,这些问题是关于在 accept() 的返回套接字中如何使用不同的端口而不是 ServerSocket 正在侦听的端口。 我一直认为 TCP 是由四组信息识别的:
Client IP : Client Port and Server IP : Server Port ->protocol (区分TCP和UDP)
那么为什么accept() 需要返回一个绑定到不同端口的套接字呢? 在每个标头中发送的四重信息是否足以区分来自不同机器的同一服务器端口的多个连接,而无需使用服务器机器上的不同端口进行通信?
然后服务器打开它自己的下一个可用端口,并将其发送给客户端。
否。它创建一个具有相同本地端口号的新套接字。 没有第二个端口号被分配或发送到客户端。 作为服务器对连接请求的响应的 SYN/ACK 段不包含第二个端口号。
在这里,客户端 A 连接到新端口,
否。客户端确认SYN/ACK 数据包,客户端在确认SYN/ACK 后连接到原始端口。 没有第二个连接。
并且服务器现在可以再次使用端口 5000。”
它总是如此。
我已经在关于 stackoverflow 的多个问题中看到了这样的答案,这些问题是关于在 accept() 的返回套接字中如何使用不同的端口而不是 ServerSocket 正在侦听的端口。
任何这样的答案都是不正确的,应该“以极端的偏见”被低估,并做出不利的评论。 TCP 握手在RFC 793 中定义,并没有指定第二个端口和第二个连接消息的分配和交换。 只有三个消息,这甚至不足以发生这种情况。
那么为什么accept() 需要返回一个绑定到不同端口的套接字呢?
它没有。
在每个标头中发送的四重信息是否足以区分来自不同机器的同一服务器端口的多个连接,而无需使用服务器机器上的不同端口进行通信?
是的。
您在 TCP 数据包标头的信息中是正确的。 它包含:
Client IP | Client Port | Server IP | Server Port | Protocol
或者,更恰当地(因为当您考虑双向传输时客户端/服务器会变得混乱):
Source IP | Source Port | Destination IP | Destination Port | Protocol
到同一服务器端口的多个连接将来自客户端上的不同端口。 一个例子可能是:
0.0.0.0:45000 -> 1.1.1.1:80
0.0.0.0:45001 -> 1.1.1.1:80
客户端端口的差异足以消除两个套接字的歧义,因此具有两个独立的连接。 服务器不需要在另一个端口上打开另一个套接字。 它确实从accept
方法接收一个套接字,但它被分配到同一个端口,现在是一条返回新接受的客户端的路由。
另一方面,FTP 确实有一个模型,其中服务器将打开一个新的非特权端口(> 1023)并将其发送回客户端以供客户端连接(这称为“被动 FTP”)。 这是为了解决客户端位于防火墙后面并且无法接受来自服务器的传入数据连接的问题。 但是,在典型的 HTTP 服务器(或任何其他标准套接字实现)中并非如此。 它的功能位于 FTP 之上。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.