2012-11-03 72 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的优化。)

你可以做的就是打开一个文件流,并复制字节到响应而不加载整个图像。上面的链接显示了这个代码。