1

最近、私はソケットを使い始めました。ネットワークストリームから読み取るとき、入ってくるデータの量がわからないことに気付きました。したがって、受信する必要があるバイト数を事前に知っているか、どのバイト知っているかのどちらかです。

現在、C# WebSocketサーバーを実装しようとしているので、HTTP 要求を処理する必要があります。HTTP リクエストは任意の長さを持つことができるため、事前に何バイトかを知ることは問題外です。ただし、HTTP 要求には常に特定の形式があります。request-line から始まり、その後に 0 個以上のヘッダーなどが続きます。このようにすべての情報があれば、単純なはずですよね?

いいえ。

私が思いついたアプローチの 1 つは、特定のバイト シーケンスが認識されるまですべてのデータを読み取ることでした。StreamReader クラスには、このように機能すると思われるメソッドReadLineがあります。HTTP の場合、妥当な区切り文字は、メッセージの本文と本文を区切る空の行です。

ここでの明らかな問題は、改行のような (できれば短い) 終了シーケンスが必要なことです。HTTP 仕様でさえ、これら 2 つの隣接する CRLF は適切な選択ではないことを示唆しています。これは、メッセージの先頭にも発生する可能性があるためです。とにかく、2 つの CRLF は単純な区切り文字ではありません。

そのため、メソッドを任意のタイプ 3 文法に拡張して、データを解析するための最良の選択は有限状態マシンであると結論付けました。ネットワーク ストリームからデータを読み取るのと同じように、バイト単位でマシンにデータを供給することができます。マシンが入力を受け入れるとすぐに、データの読み取りを停止できます。また、FSM はすぐに重要なトークンを取得できます。

しかし、これは本当に最善の解決策でしょうか? バイトごとに読み取り、カスタム パーサーで検証するのは、面倒で費用がかかるようです。そして、FSM は遅くなるか、非常に醜いものになります。そう...

フォームはわかっているがサイズがわからない場合、ネットワーク ストリームからのデータをどのように処理しますか?

HttpListenerのようなクラスがメッセージを解析し、高速に処理するにはどうすればよいでしょうか?

ここで何か見逃しましたか?これは通常どのように行われますか?

4

2 に答える 2

0

メッセージを送信したい場合は、メッセージのサイズを前に追加するだけです。メッセージのバイト数を取得し、その前に ulong を追加します。受信側で、ulong のサイズを読み取って解析し、ストリームからそのバイト数を読み取ってから閉じます。

HTTP ヘッダーでは、次を読み取ることができます: Content-Length オクテット単位の要求本文の長さ (8 ビット バイト)

于 2013-09-02T00:28:48.623 に答える