要約

  • PUSH は、後続のデータを待ち続けることなく、すでに渡されたデータを進めるよう TCP に求める。
  • PSH はレコードの印ではない。書き込み、セグメント、受信バッファー、読み取りの境界は一致しないことがある。
  • メッセージを必要とするプロトコルは、TCP より上位でフレーミングを定義しなければならない。

「レター」からバイトストリームへ

初期の TCP 仕様には「レター」という考え方があった。RFC 793 は、その仕組みが PUSH 機能として書き直されたと説明している。TCP が提供するのは境界を保持するメッセージ列ではなく、連続したオクテットのストリームである。

アプリケーションが PUSH を要求すると、すでに渡したデータを送信し、相手の利用者まで速やかに届けるよう求める。変わるのは待ち方であり、データモデルではない。

境界はそろわない

RFC 9293 では、SEND で PUSH を指定できるインターフェースなら、そのバッファーから作られた最後の TCP セグメントに PSH が設定される。ただし TCP はバッファーを分割してもよく、他のデータとまとめてもよく、連続する PUSH 指示をパケット化の際にまとめてもよい。

送信側に PUSH を示すインターフェースがない実装でも、データを無期限にバッファーしてはならない。キューにこれ以上データがなければ、最後のバッファ済みセグメントに PSH を設定する必要がある。

受信側では、PSH を見る前にバッファーが満杯になり、データがアプリケーションへ返されることがある。受信した PUSH をアプリケーションに通知するかは任意であり、通知するインターフェースでは、部分的に埋まったバッファーが返ることもある。読み取りサイズも送信側の書き込みとは別である。

したがって PSH は進行の意図であって、アプリケーション記録の終端ではない。即時送信、特定のパケット数、読み取り完了を保証するものでもない。フロー制御、輻輳制御、Nagle、実装上の制約は残る。

長さ、区切り、固定長構造など、必要なフレーミングはアプリケーションが定める。キャプチャから PSH の位置は分かっても、それだけで正式な記録境界は復元できない。

出典