networking - 为什么TCP在接收方缓冲数据

标签 networking tcp

在大多数TCP PUSH功能的描述中,都会提到PUSH特性不仅要求发送方立即发送数据(无需等待其缓冲区填满),还要求将数据推送到接收应用程序在接收端,没有被缓冲。

我不明白的是为什么 TCP 会在接收端缓冲数据?毕竟,TCP 段在 IP 数据报中传输,IP 数据报是整体处理的(即,IP 层在对携带任何给定段的 IP 数据报片段进行任何必要的重组后,仅将整个段传送到 TCP 层)。那么,为什么接收 TCP 层会等待将此数据传递给它的应用程序呢?一种情况可能是应用程序在那个时间点没有读取数据。但是,如果是这种情况,那么无论如何都不可能将数据强行推送到应用程序。因此,我的问题是,为什么 PUSH 功能需要规定有关接收方行为的任何内容?假设应用程序在段到达时正在读取数据,那么该段无论如何都应该立即传送给应用程序。

谁能帮我解答疑惑?

最佳答案

TCP 必须缓冲接收到的数据,因为它不知道应用程序何时真正读取数据并且它已经告诉发送方它愿意接收(可用的“窗口”) .所有这些数据都存储在“接收窗口”中,直到被应用程序读出。

一旦应用程序读取数据,它就会从接收窗口中删除数据,并增加它使用下一个 ACK​​ 报告给发送方的大小。如果这个窗口不存在,那么发送方将不得不推迟发送,直到接收方告诉它继续发送,而在应用程序发出读取之前它不能这样做。这将为每个读取调用增加一个完整的往返延迟延迟,如果不是更多的话。

大多数现代实现还利用这个缓冲区来保持接收到的乱序数据包,以便发送方可以只重传丢失的数据包,而不是重传它之后的所有数据包。

PSH 位通常不使用。是的,实现会发送它,但它通常不会改变接收端的行为。

关于networking - 为什么TCP在接收方缓冲数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13220956/

相关文章:

Android获取热点提供设备的IP地址

networking - GKE 中的 Pod 到 GCE 实例网络

networking - golang : network response from ioutil. ReadAll() 为空,连接被对端重置

http - NodeJS 获取 remoteAddress 使用的 IP

c++ - socket.connect 和 boost::asio::connect 之间的区别

java - 如何在 AWS Elastic Beanstalk 中托管 Java TCP 服务器

networking - 本地主机上的双栈 ipv6/ipv4

c++ - 如何使用libevent在C++中发出HEAD请求

iphone - iPhone 应用程序可以在后台因重大位置变化而唤醒进行网络事件吗?

sockets - Chrome 上的 WebRTC;我如何知道它使用的是 UDP 还是 TCP