Lol*_*ola 3 c# webserver image http
所以,我写了一个小网络服务器。首先,我尝试仅发送文本,但现在我也尝试发送图片。(或包含图片的 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);
Run Code Online (Sandbox Code Playgroud)
因此,我尝试在浏览器中打开 html 文件(其中包含图片),但它没有显示。然后,我尝试在浏览器中仅打开图片,但出现错误,指出图形无法显示,因为它包含错误。
您将所有内容编码为字符串。
对于 HTTP 标头,这很好,因为所有浏览器都希望标头能够以这种方式读取,并且必须像现在一样使用 ASCII 进行编码。
如果您要发送文本,也没有问题,因为当您未指定内容类型时,大多数浏览器默认为 ASCII 模式。
但对于图像和其他数据,您的响应中必须发生以下情况。
设置内容类型标头,指定您要发送的内容的类型。例子是
内容类型:图像/gif
或者
内容类型:图像/png
现在浏览器(或任何接收内容的东西)知道会发生什么。只不过,您使用 ASCII 编码对图像进行编码。
ASCII 仅用于将简单测试编码为字节。(我说简单,是因为 ASCII 只支持很少的字符集。它不支持多种语言等,而 Unicode、UTF 和其他一些编码则支持。)
这会导致 ASCII 将图像读取为文本,并删除或损坏它不理解的字母。(这是您的大部分图像数据。)
您想要做的是,以您在标头中指定的格式发送响应的其余部分(标头后面的图像) Content-Type
。只需发送通话结果即可ms.ToArray
。
理想情况下,您将确保图像采用您指定的正确格式,并且不依赖于文件扩展名,但实际上,许多服务器对内容类型撒谎并指定并让image/*
浏览器弄清楚。
希望这可以帮助。
顺便说一句,您的实现不擅长的是内存消耗。您使用内存流将整个图像加载到内存中,然后将其复制到数组中。也就是说,每个请求在内存中都有 2 个图像副本。我不确定您想要多少可扩展性。但是,如果您同时收到 10 个对高分辨率图像的请求(比如 5 MB,对于 8MP 相机拍摄的典型照片?),现在您的服务器会突然将 100 MB 的数据加载到内存中。
如果您在写入文件之前接受用户的文件并将其加载到内存中,这可能会成为一个更大的问题。如果用户决定上传 1 GB 的文件,则会导致您的服务器瘫痪。(我在一些用 ASP.NET 编写的网站中看到过这种情况,而且非常糟糕。故障部分是 ASP.NET 的优化造成的。)
您可以做的是打开文件流,并将字节复制到响应而不加载整个图像。上面的链接显示了此操作的代码。