首页 文章

ServerSocket是否接受任意端口上的返回套接字?

提问于
浏览
6

我在java中看到了很多类似于这个问题的答案:“假设你在端口5000上有一个带有serversocket的服务器 . 客户端A和客户端B将连接到我们的服务器 .

客户端A在端口5000上向服务器发送请求 . 客户端A侧的端口由操作系统选择 . 通常,操作系统会选择下一个可用的端口 . 此搜索的起点是先前使用的端口号1(因此,例如,如果操作系统最近发生在我们的端口45546上,那么操作系统将尝试45547) .

假设没有连接问题,服务器接收客户端A在端口5000上连接的请求 . 然后,服务器打开其自己的下一个可用端口,并将其发送到客户端 . 在这里,客户端A连接到新端口,服务器现在再次使用端口5000 . “

我在stackoverflow上的多个问题中看到了类似的答案,关于如何在accept()的返回套接字中使用不同的端口,而不是ServerSocket正在侦听的端口 . 我总是认为TCP由四方信息识别:

客户端IP:客户端端口和服务器IP:服务器端口 - >协议(用于区分TCP和UDP)

那么为什么accept()需要返回绑定到不同端口的套接字?在每个标头中发送的四重信息是否能够区分来自不同机器的多个连接到同一服务器端口,而不需要在服务器计算机上使用不同的端口进行通信?

2 回答

  • 14

    您在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之上 .

  • 4

    然后,服务器打开其自己的下一个可用端口,并将其发送到客户端 .

    不会 . 它会创建一个具有相同本地端口号的新套接字 . 没有分配或发送给客户端的第二个端口号 . 作为服务器对连接请求的响应的SYN / ACK段不包含第二个端口号 .

    此处,客户端A连接到新端口,

    否 . 客户端确认SYN / ACK数据包,并且在确认SYN / ACK后,客户端从那时起连接到原始端口 . 没有第二次连接 .

    并且服务器现在再次使用端口5000 . “

    它总是这样 .

    我在stackoverflow上的多个问题中看到了类似这样的答案,关于如何在accept()的返回套接字中使用不同的端口,而不是ServerSocket正在侦听的端口 .

    任何这样的答案都是不正确的,应该被贬低'with extreme prejudice'并对其进行评论 . TCP握手在RFC 793中定义,并未指定第二个端口和第二个连接消息的分配和交换 . 只有三条消息,甚至不足以发生这种情况 .

    那么为什么accept()需要返回绑定到不同端口的套接字?

    它没有 .

    在每个标头中发送的四重信息是否能够区分来自不同机器的同一服务器端口的多个连接,而不需要在服务器计算机上使用不同的端口进行通信?

    是 .

相关问题