HttpListener如何提供图片 [英] HttpListener how to serve images

查看:132
本文介绍了HttpListener如何提供图片的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在制作一个简单的网络服务器来提供html,css,js&图片(在C#中完成).我正在使用HttpListener,并且可以使html,javascript和css文件正常工作.我只是在图像上遇到麻烦.这是我目前正在使用的:

I'm making a simple webserver to serve html, css, js & images (done in c#). I am using HttpListener and I can get the html, javascript and css files to work properly. I am just having trouble with the images. This is what I'm using currently:

        if (request.RawUrl.ToLower().Contains(".png") || request.RawUrl.Contains(".ico") || request.RawUrl.ToLower().Contains(".jpg") || request.RawUrl.ToLower().Contains(".jpeg"))
        {
                string dir = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
                string[] img = request.RawUrl.Split('/');
                string path = dir + @"\public\imgs\" + img[img.Length - 1];

                FileInfo fileInfo = new FileInfo(path);
                long numBytes = fileInfo.Length;

                FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read);
                BinaryReader binaryReader = new BinaryReader(fileStream);
                byte[] output = binaryReader.ReadBytes((int)numBytes);
                binaryReader.Close();
                fileStream.Close();

                var temp = System.Text.Encoding.UTF8.GetString(output);
                return temp;
            }

我正在将图像转换为字符串以返回它们(这是老板建议的方式).这是我处理这些请求的方法.

I am converting the image into a string to return them (it's the way my boss suggested). This is the method where I am handling these requests.

private static string SendResponse(HttpListenerRequest request)

这是我的WebServer类的Run()方法.对SetContentType的调用仅通过request.RawUrl并确定内容类型.

This is my WebServer classes Run() method. The call to SetContentType just goes through the request.RawUrl and determines the content type.

public void Run()
    {
        ThreadPool.QueueUserWorkItem((o) =>
        {
            Console.WriteLine("StackLight Web Server is running...");

            try
            {
                while (_listener.IsListening)
                {
                    ThreadPool.QueueUserWorkItem((c) =>
                    {
                        var ctx = c as HttpListenerContext;

                        try
                        {
                            // store html content in a byte array
                            string responderString = _responderMethod(ctx.Request);

                            // set the content type
                            ctx.Response.Headers[HttpResponseHeader.ContentType] = SetContentType(ctx.Request.RawUrl);

                            byte[] buffer = buffer = Encoding.UTF8.GetBytes(responderString);


                            // this writes the html out from the byte array
                            ctx.Response.ContentLength64 = buffer.Length;
                            using(Stream stream = ctx.Response.OutputStream)
                            {
                                stream.Write(buffer, 0, buffer.Length);
                            }
                        }
                        catch (Exception ex)
                        {
                            ConfigLogger.Instance.LogCritical(LogCategory, ex);
                        }
                    }, _listener.GetContext());
                }
            }
            catch (Exception ex)
            {
                ConfigLogger.Instance.LogCritical(LogCategory, ex); 
            }
        });
    }

我的html页面需要在屏幕上显示图像,到目前为止,它显示的图像已损坏.我知道images目录是正确的,我对此进行了测试.

My html page needs to display an image to the screen, it displays a broken image so far. I know the images directory is correct, I tested that.

这是我获取网络服务器代码的地方:此处

This is where I got my code for the webserver: here

我在想,也许我必须更改SendResponse方法以不返回字符串

I was thinking that maybe I have to change the SendResponse method to not return a string

推荐答案

我知道了.我创建了一个类来保存数据,内容类型和request.RawUrl.然后,在传递字符串的地方,将其更改为传递我创建的对象.

I figured it out. I created a class to hold the data, content type and the request.RawUrl. Then, where I was passing a string, I changed it to pass the object I created.

因此,对于我的WebServer类,我的Run方法看起来像这样:

So, for my WebServer class, my Run method looks like this:

public void Run()
    {
        ThreadPool.QueueUserWorkItem((o) =>
        {
            Console.WriteLine("StackLight Web Server is running...");

            try
            {
                while (_listener.IsListening)
                {
                    ThreadPool.QueueUserWorkItem((c) =>
                    {
                        var ctx = c as HttpListenerContext;

                        try
                        {
                            // set the content type
                            ctx.Response.Headers[HttpResponseHeader.ContentType] = SetContentType(ctx.Request.RawUrl);
                            WebServerRequestData data = new WebServerRequestData();

                            // store html content in a byte array
                            data = _responderMethod(ctx.Request);

                            string res = "";
                            if(data.ContentType.Contains("text"))
                            {
                                char[] chars = new char[data.Content.Length/sizeof(char)];
                                System.Buffer.BlockCopy(data.Content, 0, chars, 0, data.Content.Length);
                                res = new string(chars);
                                data.Content = Encoding.UTF8.GetBytes(res);
                            }

                            // this writes the html out from the byte array
                            ctx.Response.ContentLength64 = data.Content.Length;
                            ctx.Response.OutputStream.Write(data.Content, 0, data.Content.Length);
                        }
                        catch (Exception ex)
                        {
                            ConfigLogger.Instance.LogCritical(LogCategory, ex);
                        }
                        finally
                        {
                            ctx.Response.OutputStream.Close();
                        }
                    }, _listener.GetContext());
                }
            }
            catch (Exception ex)
            {
                ConfigLogger.Instance.LogCritical(LogCategory, ex); 
            }
        });
    }

我的SendResponse方法如下:

And my SendResponse method looks like this:

private static WebServerRequestData SendResponse(HttpListenerRequest request)
    {
        string dir = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
        string[] fileUrl = request.RawUrl.Split('/');

        // routes
        if (request.RawUrl.Contains("/"))
        {
            // this is the main page ('/'), all other routes can be accessed from here (including css, js, & images)
            if (request.RawUrl.ToLower().Contains(".png") || request.RawUrl.ToLower().Contains(".ico") || request.RawUrl.ToLower().Contains(".jpg") || request.RawUrl.ToLower().Contains(".jpeg"))
            {
                try
                {
                    string path = dir + Properties.Settings.Default.ImagesPath + fileUrl[fileUrl.Length - 1];

                    FileInfo fileInfo = new FileInfo(path);
                    path = dir + @"\public\imgs\" + fileInfo.Name;

                    byte[] output = File.ReadAllBytes(path);

                    _data = new WebServerRequestData() {Content = output, ContentType = "image/png", RawUrl = request.RawUrl};
                    //var temp = System.Text.Encoding.UTF8.GetString(output);

                    //return Convert.ToBase64String(output);
                    return _data;
                }
                catch(Exception ex)
                {
                    ConfigLogger.Instance.LogError(LogCategory, "File could not be read.");
                    ConfigLogger.Instance.LogCritical(LogCategory, ex);
                    _errorString = string.Format("<html><head><title>Test</title></head><body>There was an error processing your request:<br />{0}</body></html>", ex.Message);
                    _byteData = new byte[_errorString.Length * sizeof(char)];
                    System.Buffer.BlockCopy(_errorString.ToCharArray(), 0, _byteData, 0, _byteData.Length);

                    _data = new WebServerRequestData() { Content = _byteData, ContentType = "text/html", RawUrl = request.RawUrl };
                    return _data;
                }
            }

我仍在清理代码,但是现在可以处理图像了!

I'm still cleaning up the code a bit but it now serves the images!

哦...这是我正在使用的对象:

Oh... And here is the object I'm using:

public class WebServerRequestData
{
    public string RawUrl { get; set; }
    public string ContentType { get; set; }
    public byte[] Content { get; set; }
    public string RawData { get; set; }
}

这篇关于HttpListener如何提供图片的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆