0

ゲーム用の簡単なプロトコルを作成しました。

b = bool
i = int
sINT: = string whose length is INT followed by a : then the string
m = int message id.

例:

m133s11:Hello Worldi-57989b0b1b0

これは:

Message ID 133
String 'Hello World' length 11
int -57989
bool false
bool true
bool false

しかし、TCP がメッセージの一部しか送信できない可能性があることを知りませんでした。次のことができるようにこれを変更する方法が正確にはわかりません。

on receive data from client:
use client's chunk parser
process data
if has partial message then try to find matching END
if no partial messages then try to read a whole message

for each complete message in queue, dispatch it

これを行うには、メッセージの先頭に B を追加し、最後に E を追加してから、最初の文字が B で最後が E になるように解析します。

唯一の問題は、途中でプロトコルに従わないばかげたものを受け取った場合はどうなるかということです. または、メッセージではなく単なる文字列を受け取るだけだとしたらどうでしょうか。したがって、文字列 HelloB を受信する意図がある場合、これを hello およびメッセージの先頭として解析しますが、メッセージではないため、そのメッセージを受信することはありません。

これらの潜在的な問題を解決するためにプロトコルを変更するにはどうすればよいですか? 正しく形成されたメッセージしか受信しないと私は予想していますが、メッセージのエンコードが不十分ですべてがうまくいかない場合は悪夢です。

ありがとう

最初に長さを追加し、メッセージに取り組んでいるかどうかを追跡することにしました:

p32m133s11:Hello Worldi-57989b0b1b0

次に、「p」を見つけるための読み取り、「p」の後の長さを見つけるための読み取り、または長さのバイトが読み取られるまでのバイトの読み取りの 3 つの状態があります。

どう思いますか?

それはうまくいくようです。

4

1 に答える 1

1

あなたがやっていることは、かなり昔ながらの磁気テープのようなものです。良い。

問題は、メッセージの一部が受信された場合、トークンの途中であるかどうかを判断できないことです。

例:受け取った場合:

m12

これはメッセージ 12 ですか、それともメッセージ 122 の最初の部分ですか?

受け取った場合:

i-12

これは整数 -12 ですか、それとも整数 -124354 の最初の部分ですか?

したがって、メッセージ番号が固定幅 (例: 4 桁)、文字列の長さが固定 (例: 6 桁)、整数の幅が 10 桁に固定されるように変更する必要があると思います。

したがって、あなたの例は次のようになります。

m_133s____11:Hello Worldi____-57989b0b1b0

そうすれば、メッセージの最初の部分を取得した場合、それを保存し、残りを受信して​​から処理することができます。

制御文字を使用してメッセージ部分を区切ることも検討してください。この目的でよく使用される ascii 制御コードには、RS、FS、GS、および US があります。したがって、メッセージは次のようになります

[RS]FieldName[US]FieldValue[RS]fieldName[US]FieldValue[GS].

[GS] が終了を示しているため、完全なメッセージが表示されていることがわかります。次に、[RS] をセパレータとして使用してフィールドに分割し、[US] を使用してそれぞれを名前/値に分割できます。

簡単な情報については、http://en.wikipedia.org/wiki/C0_and_C1_control_codesを参照してください。

于 2012-05-24T22:21:12.213 に答える