ホームページ  >  記事  >  スティッキー TCP パケットの問題を解決するにはどうすればよいですか?

スティッキー TCP パケットの問題を解決するにはどうすればよいですか?

coldplay.xixi
coldplay.xixiオリジナル
2020-06-28 13:02:557395ブラウズ

TCP スティッキー パケットの問題に対処する方法: 1. 固定長送信方式、送信側はデータ送信時にパケット化する長として LEN を使用します; 2. 送信する各データのテール マーク シーケンス方式パケットの最後に特別なバイト シーケンスを設定します; 3. ヘッダー マーキングの段階的な受信方法、ユーザー ヘッダーを定義し、ヘッダーで毎回送信されるデータ パケットのサイズを示します。

スティッキー TCP パケットの問題を解決するにはどうすればよいですか?

tcp スティッキー パケットの問題に対処する方法:

1. 設計計画 1: 修正済み送信長

データ送信時は、どんなに大きなデータを送信しても固定長にパケット化する固定長設計を採用しています(説明の便宜上、ここでは固定長を LEN として記録します)、つまり送信 データを送信するとき、エンドは LEN をパケット化の長さとして使用します。このように、受信側は固定のLENで受信するため、送信と受信が1対1で対応することができます。サブパッケージ化する場合、複数の完全な LEN パケットに完全に分割されない場合があります。通常、最後のパケットは LEN よりも小さくなります。このとき、最後のパケットは欠落部分を空白バイトで埋めることができます。

もちろん、このアプローチには欠陥があります。

1. 最後のパケットの不十分な長さは空白部分、つまり無効なバイト順序で埋められています。この無効な部分は、受信者が識別するのが困難になる可能性がありますが、これは単に埋めるためのものであり、実際には意味がありません。これにより、受信側がその意味を処理する際に問題が生じます。もちろん、フラグ ビットを追加することで補償できる解決策もあります。つまり、各データ パケットの先頭に固定長のヘッダーを追加し、データ パケットのエンド マークを一緒に送信します。受信側はこのマークにより無効なバイト列を確認し、データを完全に受信することができる。

2. 送信されるパケットの長さがランダムに分散されると、帯域幅が無駄になります。たとえば、送信長は 1,100、1000、4000 バイトなどであり、それらはすべて最大固定長である 4000 に従って送信される必要があります。4000 バイトより小さいデータ パケットを持つ他のパケットも同様に埋められます。 4000 の場合、ネットワーク負荷が無駄に浪費されます。

要約すると、この解決策は、送信されるデータ パケットの長さが比較的安定している (特定の固定値になる傾向がある) 場合により効果的です。

関連する学習の推奨事項: PHP プログラミングの入門から習熟まで

#2. 設計案 2: テール マーク シーケンス

#送信する各データ パケットの最後に 1 つを設定します特別なバイト シーケンス。このシーケンスには特別な意味があります。文字列の終了文字 "\0" と同じ意味があります。データ パケットの終わりをマークするために使用されます。受信側は、受信したデータを末尾シーケンス パケット境界を確認します。

この方法の欠陥は明らかです:

1. 受信者はデータを分析し、末尾シーケンスを識別する必要があります。

2. 末尾配列の決定自体が問題です。 「\0」のようなターミネータとして使用できるシーケンスは何ですか?このシーケンスは、「\0」が無効な文字列内容であるため文字列の終了マークとして使用できるのと同様に、人間やプログラムによって一般的に認識される意味を持たないデータ シーケンスである必要があります。では、通常のネットワーク通信におけるこのシーケンスは何でしょうか?しばらくは正解を見つけるのは難しいと思います。

3. 設計計画 3: ヘッダー タグの段階的な受信

この方法は、作成者の制限に基づいた最良の方法です。知識。効率を損なうことなく、あらゆるサイズのパケットの境界問題を完全に解決します。

このメソッドの実装は次のとおりです。ユーザー ヘッダーを定義し、ヘッダーで毎回送信されるデータ パケットのサイズを示します。受信機はデータを受信するたびに、まずヘッダーのサイズに応じてデータを読み取ります。これは 1 つのヘッダーのデータのみを読み取ります。ヘッダーからデータ パケットのデータ サイズを取得し、その後、データ パケットのデータ サイズに応じて再度読み取ります。データの内容を読み出します。

このように、各データ パケットは送信時にヘッダーでカプセル化され、受信者は 2 回に分けてパケットを受信します。1 回目はヘッダーを受信し、2 回目はデータを受信します。ヘッダーのサイズに基づいてコンテンツが決まります。 (ここでの data[0] の本質は、データのテキスト部分を指すポインタであるか、連続データ領域の開始位置である可能性があります。したがって、この場合は data[user_size] として設計できます) .)

以下は設計思想を示す図です。

スティッキー TCP パケットの問題を解決するにはどうすればよいですか?

この図から、データはヘッダーをカプセル化するアクションとともに送信され、受信側は各パケットの受信を 2 回に分割することがわかります。

このソリューションは優れているように見えますが、実際には欠陥もあります:

1. ヘッダーは小さいですが、各パケットはより多くの sizeof(_data_head) データをカプセル化する必要があり、累積影響を完全に無視することはできません。

2. 受信機の受信動作は 2 回に分けられ、データ読み取り動作が 2 倍になり、データ読み取り動作の recv または read はシステム コールとなり、システムにとって有害で​​す。言語のオーバーヘッドは完全に無視できない影響であり、プログラムへのパフォーマンスへの影響は無視できます (システム コールは非常に高速です)。

利点: プログラム設計の複雑さが回避され、その有効性の検証が容易になり、ソフトウェア設計の安定性要件を満たすのが容易になります。結論から言えば、プラン 3 が最善の策です。

以上がスティッキー TCP パケットの問題を解決するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。