知識マップ: TCPでSendした単位ごとにReceiveできるという誤解 ── バイトストリームとして扱うための受信設計

記事「TCPでSendした単位ごとにReceiveできるという誤解 ── バイトストリームとして扱うための受信設計」の主張を、概念と関係(エッジ)に分解した知識グラフの全体です。各関係には根拠・確認日・確度が付いています。

TCP通信で、送信側がSend/Writeした単位ごとに受信側でReceive/Readできるという思い込みが、分割・結合・文字化け・プロトコル破損を引き起こすことを扱う。TCPが運ぶのは順序付きのバイトストリームであり、メッセージ境界は保証されないため、受信側はアプリケーションプロトコルとしてフレーミング(固定長・区切り文字・長さプレフィックス・自己記述形式)でメッセージ境界を決める必要がある。Socket.NoDelayやDataAvailable、TLSのレコード単位はいずれもメッセージ境界の代わりにはならない。実装では、Read/Receiveの戻り値のバイト数だけを信用し、必要バイト数を読み切るまでループする設計と、本番でだけ壊れる不具合をWiresharkやpktmonで観測する手順が実務の要点になる。

TCPのバイトストリームとフレーミング設計の知識マップTCPがバイトストリームでありSend単位を保証しないこと、フレーミング方式の種類、NoDelayやDataAvailableやTLSレコードが境界の代わりにならないこと、WiresharkやpktmonでのAudit手順との関係を示す図原因になり得る防止する実装を担う実装を担う実装を担う実装を担う推奨される対応用いるのは非推奨用いるのは非推奨用いるのは非推奨原因になり得る防止する利用するで確認できるで確認できる前提とする前提とする前提とする前提とするTCPのバイトストリーム性アプリケーションプロトコルのフレーミング長さプレフィックス方式送信区切りと受信区切りのずれ(分割・結合)固定長方式区切り文字方式自己記述形式Nagleアルゴリズム(Socket.NoDelay)NetworkStream.DataAvailableTLSレコード並行Writeによるアプリケーションレベルの混線必要バイト数まで読み切る/書き切るループ非同期I/OWiresharkPacket Monitor(pktmon)Npcap

概念間の関係(全19件)

図と同じ関係を文章でも列挙します。表示している文と機械可読な意味データ(RDFa)は同じ要素に載っています。確度が「確立した関係」のものは直接の関係として、「条件付きの関係」のものは成立条件つきの言明(rdf:Statement)として表現しています。

主要概念の定義

TCPのバイトストリーム性
TCPが保証するのは送ったバイト列が順序を保って重複・欠落なく届くことだけであり、送信側のSend単位を受信側のReceive単位として保存することは保証しないという性質である。
アプリケーションプロトコルのフレーミング
受信側が、受け取ったバイト列のどこからどこまでが1メッセージなのかを判断する、アプリケーションプロトコル側の仕組みである。
長さプレフィックス方式
メッセージの先頭に本文長を置き、そのバイト数だけ本文を読むフレーミング方式で、任意のバイナリを含められ最大サイズ制限も入れやすい。
固定長方式
常に決まったバイト数を1メッセージとするフレーミング方式で、境界は明確だが可変長データを扱いにくい。
区切り文字方式
改行など特定のバイト列までを1メッセージとするフレーミング方式である。
自己記述形式
HTTPのContent-Lengthやchunkedのように、形式そのものの中に長さや終端を表す情報を持たせるフレーミング方式である。
Nagleアルゴリズム(Socket.NoDelay)
小さな送信をまとめて送るかどうかを調整するアルゴリズムで、Socket.NoDelayをtrueにすると無効化できる送信遅延・効率に関する設定である。
NetworkStream.DataAvailable
その瞬間にローカルの受信バッファに読み取り可能なデータがあるかどうかだけを示す、.NETの NetworkStreamのプロパティである。
TLSレコード
TLSが暗号化通信を運ぶ際に使う内部的な伝送単位で、アプリケーションメッセージの境界とは一致しない。
並行Writeによるアプリケーションレベルの混線
同じTCP接続に対して複数のタスクが同時にフレームを書き込むと、ヘッダーと本文の順序が混ざってしまう問題である。
必要バイト数まで読み切る/書き切るループ
Read/ReceiveやSend/Writeの戻り値が要求したサイズより少ないことがあるため、目的のバイト数に達するまで繰り返し呼び出す実装パターンである。
送信区切りと受信区切りのずれ(分割・結合)
TCPの送信単位と受信単位が一致しないために、1メッセージが複数回の受信に分割されたり、複数メッセージが1回の受信に結合されたりする現象である。
Wireshark
キャプチャしたパケットをパケット詳細ペインとバイト列ペインで対応づけて表示できる、パケット解析ツール。

機械可読データ

このページはサイトの知識グラフ(_data/knowledge/)から自動生成されています。誤りの指摘はお問い合わせからお願いします。