0

クライアントにストリーミングしたいリモートサーバーにバイナリファイルがあります。GET 要求を発行すると、応答は HTTP ヘッダー + バイナリ ファイルをチャンク単位で含む本体です。問題は、各チャンクに、必要なメタデータとバイナリ データが含まれていることです。

C# を使用して HTTP ストリームから一度に 1 つのチャンクだけを読み取るにはどうすればよいですか?

4

2 に答える 2

1

Ani のソリューションは、あなたの問題はそれをストリーミングすることではなく、元のプロトコルレベルのチャンクにアクセスすることであるため、あなたのためにそれをカットするつもりはありません. 返されたヘッダーにメタデータが追加されていない限り (そうではないと思われます)、唯一の選択肢は、ソケット レベルにドロップダウンして独自の HTTP クライアント コードを実装することです。機能をどれだけ制限できるか、およびプロトコルに慣れているかどうかによっては、これはそれほど難しくないかもしれません。

編集

ソケットを開き、整形式の HTTP 1.1 要求を送信してからすべてを読み返すと、最初の応答ヘッダーの後にいくつかのチャンクが続くことがわかります。各チャンクにはミニヘッダーがあり、その後に関連データが続きます。これらのミニヘッダーに情報が必要な場合は、そこにありますが、応答ヘッダーを解析する必要があるのと同じように、自分ですべてを解析する必要があります。これらの詳細は、高レベルのプロトコル クラスを使用するときにすべて処理されますが、その場合も詳細は隠されます。これは、特別なニーズにとっては問題です。

ここで、最初のチャンク ヘッダーまで読み取ると、そのチャンクの長さが含まれるため、チャンクの最後まで読み取ることができるバイト数が正確にわかります。私は信じていますが、そのチャンクの最後を超えて読み取ろうとしたときに次のチャンクが送信されなかった場合、Socket.Receive可能な限り読み取って実際のバイト数を返すと確信しています。いずれにせよ、注意していれば、2 番目のチャンクがまだ送信されている間に最初のチャンクの処理を開始できます。

それは役に立ちますか?

于 2010-09-15T18:18:49.710 に答える
1

他の人が指摘したように、Read() を発行して、データの 1 つのチャンクを取得することを期待することはできません。HTTP は、ストリーミング プロトコルである TCP を使用します。これは、送信者が 1024 バイトを書き込んだ場合、リーダーは 1 バイトの 1024 回の読み取り、または 1024 バイトの 1 回の読み取り、またはその間のデータを取得できることを意味します。

また、この理由により、基盤となるプロトコルはまだ TCP であるため、ソケットにダウンしても役に立ちません。

だから、あなたはそれを難し​​い方法でやらなければなりません。メタデータを含む必要なバイト数を取得するのに十分な量の Read() を最初に実行するステート マシンを作成する必要があります。このバイト配列を解析して、メタデータを取得します。次に、残り (ある場合) をバッファリングし、読み取りを続けてデータ部分を取得します。泡立てて、すすぎ、の繰り返し…

于 2010-09-16T03:47:32.357 に答える