sockets - 为什么TCP套接字编程需要两个套接字(一个欢迎套接字和一个连接套接字)而UDP只需要一个?

标签 sockets tcp

这是不是因为TCP连接是持久连接,所以服务器需要同时处理很多请求,因此需要不同的连接套接字?

但是如果 UDP 传输完成,下一个连接将发起到同一个服务器套接字,所以 UDP 只需要一个套接字。

这是我的推测。 这是正确的吗?

最佳答案

原因是 TCP 有两种不同的状态需要控制,而 UDP 只有一种。

当监听端口上的 TCP 连接时,网络堆栈需要跟踪端口号和你正在监听的接口(interface),以及传入的 TCP 连接请求的积压列表套接字,并将该状态保存在与您传递给 listen()/bind()/accept() 的套接字关联的内部数据结构中。只要套接字存在,该数据结构就会更新,并在您关闭()该套接字时被丢弃。

另一方面,一旦您接受了 TCP 连接,accept() 返回的新 TCP 套接字就会有其自己的特定于连接的状态,需要单独跟踪——该状态由客户端的 IP 地址和来源组成端口、TCP 数据包 ID 序列、TCP 窗口大小和发送速率、已为该 TCP 连接接收的传入数据、已为该 TCP 连接发送的传出数据(如果数据包丢失,可能需要稍后重新发送)等等。所有这些都存储在一个单独的内部数据结构中,该数据结构专门与该新套接字相关联,该数据结构将被更新,直到该新套接字被关闭(),此时它将被丢弃。

请注意,这两种状态的生命周期彼此非常独立——例如,您可能决定不想再接受任何传入的 TCP 连接,因此您想要关闭第一个 (连接接受)套接字,同时继续使用第二个(特定于 TCP 连接的)套接字与已连接的客户端通信。或者您可能会做相反的事情,并决定您不想继续与该特定客户端的对话,因此您关闭了第二个套接字,但您确实希望继续接受更多的 TCP 连接,因此您让第一个套接字保持打开状态。如果只存在一个套接字来处理所有事情,那么只关闭一个上下文或另一个上下文是不可能的;您唯一的选择是 close() 单个套接字,它会丢失所有状态,甚至是您实际想要保留的部分。这充其量会很尴尬。

另一方面,UDP 没有“接受连接”的概念,因此只有一种状态,即缓冲发送和/或接收数据包的集合(不管它们的来源和/或目的地).因此,通常不需要超过一个 UDP 套接字。

关于sockets - 为什么TCP套接字编程需要两个套接字(一个欢迎套接字和一个连接套接字)而UDP只需要一个?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41389880/

相关文章:

java - TCP 连接 Socket.getInputStream()

java - "delay"在使用 sun HttpServer 时传递 WebService 回复

linux - 如何设置 linux 内核不发送 RST_ACK,这样我就可以在原始套接字中提供 SYN_ACK

php - TCP CLOSE_WAIT 连接状态 - 未知原因

c# - 为什么将 SocketOptionName.HeaderIncluded 设置为 true 时会出现 SocketException 10022?

c++ - Windows 上套接字号的 PID?

java - 方法 Socket(String, int) 未定义类型

c# - TCP/IP客户端服务器在c#中通过不同网络进行通信

java - 为什么这段代码只能在带有断点的 Debug模式下工作? (IDE调试器)

c# - TCP 服务器/客户端连接问题 C#