摘要

  • PUSH 要求 TCP 不要为了等待更多应用数据而无限期停留。
  • PSH 不是记录标记;写入、分段、接收缓冲区和读取操作可以拥有不同边界。
  • 需要消息结构的应用必须在 TCP 之上定义自己的分帧规则。

从“信件”到连续字节流

早期 TCP 规范曾尝试使用“信件”概念。RFC 793 说明,这一机制后来被重新表述为 PUSH 功能。这个变化揭示了核心模型:TCP 提供连续的八位字节流,而不是能够保留边界的消息序列。

应用请求 PUSH 时,是要求已经提交的数据尽快向前传送并交付给远端用户。它改变的是允许等待的方式,不是数据的类型。

边界不会自动对齐

RFC 9293 规定,如果发送接口允许应用在 SEND 中指定 PUSH,PSH 会放在由该缓冲区生成的最后一个 TCP 分段上。但 TCP 仍可能拆分缓冲区、合并数据,或在分段时合并连续的 PUSH 请求。

如果实现没有向发送端提供 PUSH 接口,它也不能无限期缓存数据;当队列中已无更多数据时,必须在最后一个已缓存分段上设置 PSH。

接收端的缓冲区可能先填满,于是数据在看到 PSH 之前就被交给应用;规范并不强制接口向应用暴露 PUSH 指示,但如果接口选择暴露,PSH 也可能导致部分填充的缓冲区被返回。应用读取的大小同样不必对应发送端写入的大小。

因此 PSH 表示传输进度意图,而不是应用记录的终点。它不保证立即发送、固定的分段数量或一次读取完成。流量控制、拥塞控制、Nagle 以及具体实现仍然有效。

需要消息的协议应自行携带长度、分隔符、固定大小结构或其他分帧规则。抓包可以显示某次分段中 PSH 出现的位置,却不能仅凭该位恢复权威的应用记录边界。

来源