0

Linux は、ソケットで受信したすべての受信メッセージをバッファリングします。しかし、受け取る前に、このメッセージには始まりと終わりがありました。Linux はこのメッセージをバッファに順番に書き込むため、メッセージの終わりの情報が失われます。

Linux では cmsg_header を使用できることはわかっていますが、Windows では send-/recvmsg() プロシージャが提供されていません。platformagnostic バッファでメッセージの終わりを判断するにはどうすればよいですか?

4

5 に答える 5

5

TCP/IP 接続が適切に区切られたメッセージを交換しているかどうかはわかりません。ルーターはパケットを断片化する可能性があります。(そのcmsg_headerため、信頼できない可能性があります)。

私が知っているすべての TCP/IP ベースのプロトコル (HTTP、SMTP、X11、RPCXDR) は、アプリケーション レベルでメッセージ編成を処理しています。アプリケーションライブラリは、「メッセージ」がいつ、いつ開始または終了するかを何らかの形で知る必要があります。

于 2012-11-11T16:29:50.683 に答える
4

最初の 4 バイトで、メッセージの長さをネットワーク順に送信するだけです。その後、この問題は発生しません。

于 2012-11-11T16:31:49.020 に答える
2

sendmsgWinsock に相当する、recvmsgは、WSASendMsgと思いますWSARecvMsgドキュメントLPWSAMSGによると、msghdr 構造体の Posix.1g 仕様に基づく構造体である引数を取ります。

于 2012-11-11T16:41:49.843 に答える
1

Linux はこのメッセージをバッファに順番に書き込むため、メッセージの終わりの情報が失われます。

それは正しくありません。受信側で失われる「メッセージの終了に関する情報」はまったくありませんでした。TCP はバイト ストリーム プロトコルです。send()s またはs は、sender でソケット送信バッファに連結され、そこからデータwrite()がTCP セグメントと IP パケットで送信されましたが、トランスポートはそうすることにしました。

TCP 経由のメッセージが必要な場合は、完全に自分で実装する必要があります。一般的なテクニック:

  • メッセージの前に長さの単語を送信する
  • たとえば、STX と ETX の間で、ETX がメッセージ内で発生する場合は適切なエスケープ (ESC ETX) を使用してメッセージをカプセル化し、メッセージ内で発生する場合は ESC 自体 (ESC ESC) をエスケープします。
  • XML などの自己記述型プロトコルを使用します。
于 2012-11-13T07:34:04.373 に答える
1

ネットワークに面したアプリケーションは、通常、トランスポートとビジネス ロジックが明確に分離されています。

ビジネス層はメッセージ全体のみを操作します。トランスポートはメッセージ全体を上流のビジネス層に配信し、フラグメントから連続ストリームを組み立て、再スライスし、一連のメッセージとして再解釈する可能性があります。

トランスポート層は通常、[サイズ (長さ = S)] [ペイロード (可変長)] の形式のプロトコル メッセージを使用して、リモート トランスポート層と通信します。ここで、[サイズ] は、マーシャリングされた長さ S がすべての通信相手に知られている単一の数値です。

トランスポート層が最初に行うことは、ダウンストリームから S バイトを受信するのを待機することです (非同期か同期かは関係ありません) 一時バッファーに入れます。完了すると、受信したデータをアンマーシャルし、受信するペイロードの長さ L を認識するようになります。

ペイロードの長さが L になると、トランスポートは L バイトをダウンストリームから一時バッファーに受信するのを待機し (複数の読み取りを組み合わせる必要がある場合があります)、完了するとアプリケーション層に通知し、組み立てられたメッセージ全体を 1 つのバッファーに渡します。

于 2012-11-11T16:37:49.130 に答える