私はソケットを初めて使用し、オンラインでチックタクトを作成しています。クライアントとサーバーとの接続方法は知っていますが、チャットも行います。
次に、ユーザーがチャットするときにプレフィックス「CHAT:HELLO WORLD」を含むメッセージを送信し、ユーザーが移動するとプレフィックスなしでメッセージを送信します...これが最善の方法ですか?
THX!!!
TCPのようなストリームベースのプロトコルを介してワイヤプロトコルを定義する場合、メッセージを作成するためのいくつかのオプションがあります。
x
バイトのすべてのシーケンスは、新しいメッセージを表します。\n
。プロトコルを変更する予定がある場合(ヒント:変更するとは思わない場合でも変更します)、古いものを使用しているクライアントを処理する際の問題を防ぐために、各メッセージにプロトコルバージョンの識別子を含めることが重要です。プロトコルの反復。明らかに、これは残りのペイロードを解読する前に最初に決定する必要があるものなので、これはメッセージの最初のバイトである必要があります(任意の長さのプレフィックスに続く)-そうでない場合、どのようにバージョンを決定できますか私たちが受け取るすべてのメッセージのどこにあるか知っていますか?
通常、パケットの長さ、タイプ、およびペイロードを含む形式を使用します。
あなたの場合、Byte(タイプ)、Int16(長さ)、Byte [](ペイロード)を使用できます。
タイプは、コードで列挙型として表すことができます。長さは、ペイロードの長さを表すだけです。
public enum Byte PacketType {
PlayerMove = 1,
PlayerChat = 2
}
プロトコルを定義する必要があります。追加機能のための余地を残すことを忘れないでください:-)。
例えば。完全な行に対して正規表現を使用する (選択した行ターミネータで終了):
^:[a-c][1-3]:
: 移動 (コロン、位置、コロン ユーザー名) です。^!.*?:
: チャット メッセージ (感嘆符、名前、コロン、テキスト) です。それ以外 (V1) はエラーです。
覚えて:
TCPを使用していると思いますか?
両方のメッセージを「フレーム化」して、それらを識別し、潜在的なブロッキングの問題を回避できるようにする必要があります(CHAT:または定義したものを読むことを期待しているときにクライアントが送信を停止した場合)。TCPを使用すると、バイトオーダーは保証されますが、読み取りは完全な「パケット」を保証しないため、バッファを構築し、「メッセージ」がいつ完了したかを識別する何らかの方法を実装する必要があります。
これを行うためのかなり簡単な方法は、各「メッセージ」に、指定されたタイプとサイズのヘッダーがあることを確認することです。
例えば:
メッセージタイプ(現在は移動してチャット)を列挙します。たとえば、「チャット」は0x01で、メッセージは1020バイトです。'message'の前に0x0103FCを付けると、サーバーは予想されるバイト数を認識し、1020バイトが読み取られるまで(またはクライアントが送信しないと任意に決定するまで)非同期ソケット呼び出しを使用してバッファーを構築できます。