2012-11-03 108 views
2

所以,我寫了一個小的網絡服務器。首先,我試圖只發送文本,但現在我也試圖發送圖片。 (或HTML的網頁,其中包含圖片)網絡服務器發送圖片通過HTTP

這是我已經試過:

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文件(包含圖片)的瀏覽器,但它不」 t出現。然後,我試圖在瀏覽器中只打開圖片,但是接着出現一個錯誤,表示圖形無法顯示,因爲它包含錯誤。

+0

嘗試在調用'ms.ToArray()'之前調用'ms.Close()'。因爲文檔中說ToArray在流關閉時工作。 http://msdn.microsoft.com/en-us/library/system.io.memorystream.toarray.aspx – Madushan

+0

謝謝你的提示,但不幸的是它沒有任何區別 – Lola

+0

嗯...可能是因爲最後一行用ASCII編碼所有東西,你的圖像現在已經損壞了? 嘗試獲取ASCII字節的頭部,但不是'responseContent'並將兩個數組合併成一個較大的數組.. – Madushan

回答

1

您編碼的一切作爲一個字符串。

對於HTTP標頭,這是好的,因爲所有的瀏覽器預計頭讀取這樣的,它必須使用ASCII因爲你現在做的編碼。

如果你發送短信,也很好,因爲大多數瀏覽器默認爲ASCII模式時,您不指定內容類型是什麼。

但對於圖像和其他數據,按照你的反應一定會發生。

設置內容類型頭指定您要發送的內容的類型。 例子是

內容類型:圖像/ GIF

內容類型:圖像/ PNG

現在瀏覽器(或任何其正在接收內容)知道期望什麼。除此之外,您使用ASCII編碼編碼圖像。

ASCII僅是一種用於編碼簡單測試以字節。 (我說簡單,因爲ASCII只支持很少的一組字符,它不支持多種語言,例如Unicode,UTF和其他編碼)。

這會導致ASCII讀取圖像,作爲文本,並去掉或破壞它不理解的字母。 (這是您的大部分圖像數據。)

您想要做的是以Content-Type標頭中指定的格式發送其餘響應(圖像,標題後)。只需發送ms.ToArray呼叫的結果。

理想情況下,您將確保圖像格式符合您指定的格式,並且不依賴於文件擴展名,但實際上,很多服務器對內容類型撒謊並指定image/*並讓瀏覽器圖出來。

Here's a good example on how to build a web server in C#.

希望這有助於。


在附註中,你的實現不好的是內存消耗。您正在使用內存流將整個圖像加載到內存中,然後將其複製到一個數組中。這是每個請求的內存中的2個副本。我不確定你想要多少可擴展性。但是,如果您同時獲得10個高分辨率圖像的請求(例如5 MB,對於800萬像素攝像機拍攝的典型照片?),現在您的服務器突然將100 MB數據加載到內存中。

如果您在寫入文件之前接受用戶的文件並將其加載到內存中,這可能會成爲一個更大的問題。如果用戶決定上傳1 GB的文件,則會導致服務器無法使用。 (我已經看到了這個在與ASP.NET編寫一些網站的行動,這是非常糟糕的。故障部分是ASP.NET的優化。)

你可以做的就是打開一個文件流,並複製字節到響應而不加載整個圖像。上面的鏈接顯示了這個代碼。