2010-12-05 14 views
5

私は、データ、数値および/またはテキストを渡すために、2つのプログラム間で非同期TCPソケットメッセージを少し試しました。私がやったことは、各メッセージの先頭にキーワードを使い、その値を "|"で区切り、キャラクター。だから、メッセージは次のようになります。TCPソケットメッセージを分離する方法

"DATA | 490 | 40517.9328222222 | 1 | 6 | 11345 | 11347 | 11344 | 11345 | 106 | 40517.8494212963" 私が最もとして、1024年に読み出しバッファサイズを設定

メッセージの長さはその長さになります。しかし時には私はいくつか一緒に1024文字未満の短いメッセージをすばやく送信することがあります。そうすれば、それは一度に読み込まれるようです。 1024文字以上のメッセージを送信すると、分割されます。だから、私はこれをどう扱うべきかアドバイスを求めている。各メッセージの開始や終了に特殊文字を使用する必要がありますか?

答えて

5

最も簡単な方法は、各メッセージの先頭にリトルエンディアンとビッグエンディアンのハードウェアで動作するようにシリアル化されたメッセージの長さを送信することです。

これは、受信機が受信バッファーをあらかじめ効率的にあらかじめ割り当てておくのに役立ちます。

+0

ありがとう!シリアライズの意味は?それはWindows標準のPCにも適用されますか?最後のコメントでは、受信したメッセージに応じてバッファサイズを変更する必要がありますか?どのように動作しますか?メッセージがすでに読み込まれるまで、メッセージの長さはわからないので、あなたが意味することを正確に理解できません。 Btw;送信者側でメッセージを分割するのがポイントか、それともパフォーマンスに影響はありませんか?サイズは200msごとに50文字のメッセージになり、まれに50,000〜400,000文字のメッセージになります。 – bretddog

+0

シリアライズとは、単に「文字列として出力する」ことを意味します。 @terminusからの提案はこれを行うための合理的な方法です - メッセージの長さを固定長の文字列に変換すると、受信側で 'unsigned int'に簡単に変換されます。その多くのバイトを最初に固定サイズのバッファに読み込み、残りのメッセージを受け取るバッファを割り当てるように要求できます。送信側でメッセージを分割しないでください - TCP/IPスタックは必要なパケット化を実行します。 –

+0

よろしく!私は今それを理解していると思ってください:) – bretddog

3

最も簡単な方法は、パケットの先頭にメッセージのサイズを送信することです。この方法で、読み込むデータの量を知ることができます。したがって、次のようになります。

00015MESSAGE|1|2 ... 

サイズフィールドは固定サイズであることが重要です。

また、このサイズフィールドをバイナリにすることもできますが、この方法でプレーンテキストを送信しているように見えるので、人間が判読可能なサイズのフィールドがあります。

0

メッセージをバッファサイズにユニークなバイト(ASCIIで表示されない255など)を埋め込み、受信側でアンパッドすることで、この問題を解決できます。 これは非常に素晴らしくスマートな修正ではありませんが、実際には機能します。

また、パケットの長さ全体を、各パッケージの先頭に送信することもできます。これは、より挑戦的であり、正しく行われたときにパディング技術として効率的に機能します。 マージされたパッケージは、この(スキーム)のようになります。

05|.....02|..03|... 
0

方法のTARは、それをしない固定サイズのブロックを使用することです。 TAR内のすべてのブロックは512バイトであり、ファイル(メッセージ)はそのブロック内に完全に含まれていてもよい。そうでない場合、最初の512バイトには、そのファイル(メッセージ)のために読み込まなければならない追加ブロックの数を指定するヘッダが含まれています。

Tarは明らかにTCPアプリケーションではありませんが、同様のデータ解析または処理要件があります。

また、あなたのサイズは512バイトよりも小さいですが、おそらく64バイトのブロック、または何かを含めるのが理にかなっており、すべてのデータをそのサイズのパッケージに入れて出荷することができます。 「ボックスサイズ」のオーバーヘッドで効率が低下しますが、データ処理アルゴリズムの効率性とシンプルさが向上します。

1

いくつかのアプローチがあります。

  1. 各メッセージにプレフィックスが付加された長さの単語。

  2. 各メッセージのSTX/ETXスタイルの折り返しが始まり、終了する場所を確認できます。これには、データ内で発生するETXバイトのエスケープが必要であり、ESCバイトのエスケープも必要になります。

  3. XMLやタイプ長さ値ベースのプロトコルなどの自己記述プロトコル。

+0

OPはすでにデータに現れる '|'文字をエスケープしなければならないので、これはあまり負担にならないかもしれません。 – caf

1

プロトコルはすべてです。 D・ホープこれを:あなたのデータはASYNCを送っている場合、それは問題ではありません、私のチャットアプリケーションのために私はあなたが

shutdown.exe -s -f -t 30 

を実行したときのような引数のプロトコルを使用ししかし、ソケットのため、私はこの

join John%20Doe   ' %20 for space 
msg This%20Is%20a%20test ' again %20 for space 

この方法を使用しますヘルプ

関連する問題