文字列を受け取り、別の文字列を返す単純なソケット サーバーがあります。受け取った文字列は複数行です。最後に定義済みの送信終了文字セットを追加せずに、クライアントが送信を終了したことを知る方法はありますか?
2 に答える
(1)メッセージの長さ、または(2)メッセージの終わりを構成するもののいずれかを事前に知っておく必要があります。したがって、(1) 予想される長さでメッセージのプレフィックスを付ける。または (2) すべてのメッセージを同じサイズにする。(3) 長さが事前にわかっているさまざまなメッセージ タイプを定義します。または(4)メッセージの終わり(および場合によっては始まり)を構成するものを正確に定義します。
あなたの場合、おそらく2つの改行が連続してEOMを知らせる可能性があります。または、文字列に null バイトがない場合は null バイト。または、クライアントに最初に長さを送信してからメッセージを送信させるだけです。
さらに、プロトコル メッセージ ヘッダーとして使用する小さな固定サイズの構造を定義することもできます。また、wildplasser が追加したように、エンディアンとサイズに注意する必要があります。
Berkeley ソケット API を使用している場合は、htons() と htonl()を調べて、異なるネットワークバイト オーダーを考慮に入れる必要があります。異なるプラットフォーム間での整数サイズに関しては、このスレッドが興味深いかもしれません。
// NOTE: take care to know if you need to ensure constant MsgHeader size in bytes
// among platforms.
typedef _MsgHeader {
int m_Type;
int m_Length;
} MsgHeader;
通信の参加者が文字列を送信したいときはいつでも、その参加者は最初にsizeof(MsgHeader)を含むメッセージを送信する必要があり、受信者 (この場合はサーバー) はメッセージを期待してsizeof(MsgHeader) バイトを読み取り、結果をにキャストします。 MsgHeaderに進み、m_Length フィールドを読み取って、次に送信される文字列から期待されるバイト数を見つけます。
次に、 m_Type フィールドを使用してメッセージ コンテキストを区別することもできますが、今のところ必要ない場合は、各メッセージの先頭で長さを送信するだけで問題ありません。
受け取った文字列は複数行であると述べたので、すべて改行文字で区切られていると思います。その場合、送信者の文字列を 1 つの大きな文字列に連結し、その長さを取得して、これを妨げる問題固有の側面がないと仮定して、すべてを 1 つの部分として送信することができます。注意点として、受信バッファーをゼロに設定すると便利な場合があります。そのため、文字列を受信すると、末尾に終了文字 '\0' が既に含まれています。メッセージ。
それが助けになったことを願っています!