3

それで、私は小さなWebサーバーを書きました。最初はテキストだけを送ろうとしましたが、今は写真も送ろうとしています。(または画像を含む html ページ)

これが私が試したことです:

if ((Path.GetExtension(filename).ToLower() == "jpg") || (Path.GetExtension(filename).ToLower() == "png") || (Path.GetExtension(filename).ToLower() == "gif"))
{
    Image image = Image.FromFile(filename);
    MemoryStream ms = new MemoryStream();
    image.Save(ms, image.RawFormat);
    responseContent = Encoding.Default.GetString(ms.ToArray());
    responseheader = "HTTP/1.1 200 OK\r\n" +
                     "Server: MiniWebServer\r\n" +
                     "Content-Length: " + responseContent.Length + "\r\n" +
                     "Content-Language: de\r\n" +
                     "Connection: close\r\n\r\n"; 
}

finalResponse = responseheader + responseContent;
return Encoding.ASCII.GetBytes(finalResponse);

それで、ブラウザでhtmlファイル(画像を含む)を開こうとしましたが、表示されません。次に、ブラウザで画像だけを開こうとしましたが、エラーが含まれているためグラフィックを表示できないというエラーが表示されます。

4

1 に答える 1

4

すべてを文字列としてエンコードします。

HTTP ヘッダーの場合、これは問題ありません。すべてのブラウザーは、ヘッダーがこの方法で読み取れることを期待しており、現在行っているように ASCII を使用してエンコードする必要があるためです。

テキストを送信する場合も問題ありません。コンテンツ タイプを指定しないと、ほとんどのブラウザはデフォルトで ASCII モードになるからです。

ただし、画像やその他のデータの場合は、応答で次のことが発生する必要があります。

送信するコンテンツのタイプを指定するContent Typeヘッダーを設定します。例は

コンテンツタイプ: image/gif

また

コンテンツ タイプ: 画像/png

これで、ブラウザー (またはコンテンツを受信するもの) は、何を期待するかを認識します。ただし、画像を A​​SCII エンコーディングでエンコードしました。

ASCII は単純なテストをバイトにエンコードするためだけのものです。(ASCII はごくわずかな文字セットしかサポートしていないため、シンプルと言います。Unicode、UTF、およびその他のエンコーディングがサポートする複数の言語などはサポートしていません。)

これにより、ASCII は画像をテキストとして読み取り、理解できない文字を削除または破損します。(これはほとんどの画像データです。)

やりたいことは、ヘッダーで指定した形式で残りの応答 (ヘッダーの後の画像) を送信することですContent-Typems.ToArray呼び出しの結果を送信するだけです。

理想的には、画像が指定した正しい形式であることを確認し、ファイル拡張子に依存しないようにしますが、実際には、多くのサーバーがコンテンツ タイプについて嘘をつき、指定image/*してブラウザーに認識させます。

C# で Web サーバーを構築する方法の良い例を次に示します。

お役に立てれば。


余談ですが、実装が苦手なのはメモリ消費です。メモリ ストリームを使用してイメージ全体をメモリにロードし、それを配列にコピーします。これは、リクエストごとにメモリ内のイメージの 2 つのコピーです。どの程度のスケーラビリティが必要かわかりません。しかし、高解像度の画像 (たとえば、8MP カメラで撮影した典型的な写真の場合は 5 MB ?) に対して同時に 10 件の要求を受け取った場合、サーバーは突然 100 MB のデータをメモリにロードします。

ユーザーからファイルを受け取り、ファイルに書き込む前にそれらをメモリにロードしている場合、これはより大きな問題になる可能性があります。ユーザーが 1 GB のファイルをアップロードしようとすると、サーバーがダウンします。(ASP.NET で書かれたいくつかのサイトでこれが動作しているのを見たことがありますが、非常に悪いです。障害の一部は ASP.NET の最適化です。)

できることは、ファイル ストリームを開き、イメージ全体を読み込まずにバイトを応答にコピーすることです。上記のリンクは、このコードを示しています。

于 2012-11-04T03:22:59.867 に答える