2

ソケットから TCP パケットを解析するのに問題があります...

私のプロトコルでは、メッセージは次のようになります。

'A''B''C''D''E'........0x2300

'A''B''C''D''E' --> メッセージ パターンの開始

0x2300 --> 2 バイトの終了メッセージ

しかし、Nagle のアルゴリズムにより、メッセージが次のように連結されることがあります。

'A''B''C''D''E'........0x2300'A''B''C''D''E'........0x2300 'A''B''C''D''E'........0x2300

私はすでにsetNoDelay()真にしようとしましたが、問題は解決しません。

私はバイト[]にメッセージを持っています。

メッセージを分割して個別に解析するにはどうすればよいですか?

PS: 今のところ、最初のメッセージを取得できますが、他のメッセージは失われています...

4

3 に答える 3

3

受信したデータをループしてエンドマーカーをチェックするだけです。見つかったら、開始インデックスを次のパッケージに設定し、検索を続けます。このようなもの:

int packageStart = 0;
for(int i = 0; i < data.length - 1; i++) {
  if(data[i] == 0x23 && data[i + 1] == 0x00) {
      // Found end of package
      i++;
      processPackage(data, packageStart, i);
      packageStart = i;
  }
  // At this point: from packageStart till data.length are unprocessed bytes...

前述のように、データが残っている可能性があります (dataエンドマーカーで終わっていない場合)。受信したデータの次のバッチに追加できるように、保持したい場合があります。したがって、TCP/IP パッケージの切り刻みによるデータ損失を防ぎます。

于 2013-01-07T16:01:41.090 に答える
2

連続するバイト ストリームを解析していると考える必要があります。コードでは、メッセージの開始と終了を識別する必要があります。

パケットが送信される方法により、完全なメッセージ、複数のメッセージ、部分的なメッセージなどがある場合があります。コードは、メッセージがいつ開始されたかを識別し、メッセージの終わりが見つかるまで、または何らかのインスタンスで読み取り続ける必要があります。 、最大メッセージサイズよりも多くのバイトを読み取ったため、再同期する必要がある場合。

一部の通信マネージャーが接続を切断して再確立する (最初からやり直す) のを見たことがありますが、同期が戻るまでデータを破棄する通信マネージャーもいます。次に、保証された配信と再送信が必要かどうかという楽しみに取り掛かります。

最良のプロトコルは単純なものです。たとえば、SOH バイト、2 バイトのメッセージ長 (または適切なもの)、2 バイトのメッセージ タイプ、および 1 バイトのメッセージ サブタイプを含むメッセージ ヘッダーを作成します。任意のバイト数でメッセージを終了することもできます。ASCII チャートを見てください。端末時代からかなり標準的な 16 進バイト 00-1F がいくつかあります。

ここで車輪を再発明しても意味がありません。データ内のパターンを探す代わりに、このメッセージの長さを知っているので、簡単になります。

于 2013-01-07T16:16:42.833 に答える
-2

EOF コード 0x2300 が表示されるまで、これをバイト ストリームのように扱い、パケットをバッファリングする必要があるようです。

于 2013-01-07T16:03:44.470 に答える