1

私はソケットを初めて使用し、オンラインでチックタクトを作成しています。クライアントとサーバーとの接続方法は知っていますが、チャットも行います。

次に、ユーザーがチャットするときにプレフィックス「CHAT:HELLO WORLD」を含むメッセージを送信し、ユーザーが移動するとプレフィックスなしでメッセージを送信します...これが最善の方法ですか?

THX!!!

4

4 に答える 4

4

TCPのようなストリームベースのプロトコルを介してワイヤプロトコルを定義する場合、メッセージを作成するためのいくつかのオプションがあります。

  • 固定長
    • すべてのメッセージは同じ長さです。xバイトのすべてのシーケンスは、新しいメッセージを表します。
  • 長さプレフィックス(可変長)
    • メッセージの最初のバイトは、続くペイロードの長さを表します。
  • 文字列で終了します(可変長)
    • メッセージの終わりを表す指定されたバイト文字列、つまり改行文字に到達するまで、ストリームからバイトを読み取ります\n

プロトコルを変更する予定がある場合(ヒント:変更するとは思わない場合でも変更します)、古いものを使用しているクライアントを処理する際の問題を防ぐために、各メッセージにプロトコルバージョンの識別子を含めることが重要です。プロトコルの反復。明らかに、これは残りのペイロードを解読する前に最初に決定する必要があるものなので、これはメッセージの最初のバイトである必要があります(任意の長さのプレフィックスに続く)-そうでない場合、どのようにバージョンを決定できますか私たちが受け取るすべてのメッセージのどこにあるか知っていますか?

于 2012-08-01T15:17:58.853 に答える
4

通常、パケットの長さ、タイプ、およびペイロードを含む形式を使用します。

あなたの場合、Byte(タイプ)、Int16(長さ)、Byte [](ペイロード)を使用できます。

タイプは、コードで列挙型として表すことができます。長さは、ペイロードの長さを表すだけです。

public enum Byte PacketType {
  PlayerMove = 1,
  PlayerChat = 2
}
于 2012-08-01T14:39:58.587 に答える
1

プロトコルを定義する必要があります追加機能のための余地を残すことを忘れないでください:-)。

例えば。完全な行に対して正規表現を使用する (選択した行ターミネータで終了):

  • 一致^:[a-c][1-3]:: 移動 (コロン、位置、コロン ユーザー名) です。
  • マッチング^!.*?:: チャット メッセージ (感嘆符、名前、コロン、テキスト) です。

それ以外 (V1) はエラーです。

覚えて:

  • データはパケットで送信されます。完全なメッセージを取得するには、ソケットから複数回読み取る必要がある場合があります。
  • あいまいさを避ける: x または y である可能性があることを解決するのは困難です。
  • テキストエンコーディングを指定します (例: UTF-8)。
于 2012-08-01T14:38:35.367 に答える
0

TCPを使用していると思いますか?

両方のメッセージを「フレーム化」して、それらを識別し、潜在的なブロッキングの問題を回避できるようにする必要があります(CHAT:または定義したものを読むことを期待しているときにクライアントが送信を停止した場合)。TCPを使用すると、バイトオーダーは保証されますが、読み取りは完全な「パケット」を保証しないため、バッファを構築し、「メッセージ」がいつ完了したかを識別する何らかの方法を実装する必要があります。

これを行うためのかなり簡単な方法は、各「メッセージ」に、指定されたタイプとサイズのヘッダーがあることを確認することです。

例えば:

メッセージタイプ(現在は移動してチャット)を列挙します。たとえば、「チャット」は0x01で、メッセージは1020バイトです。'message'の前に0x0103FCを付けると、サーバーは予想されるバイト数を認識し、1020バイトが読み取られるまで(またはクライアントが送信しないと任意に決定するまで)非同期ソケット呼び出しを使用してバッファーを構築できます。

于 2012-08-01T14:40:48.353 に答える