none
HttpListener初次使用,编写迷你http服务器,启动,访问一直不成功,收不到请求,怎么解决? RRS feed

  • 问题

  • 想构造迷你的http服务器,通过桌面程序启动,复制网上HttpListener简单的演示代码,端口自定义。启动后,访问时能访问,但页面显示的是400错误,请求方法一直没被调用

    启动http服务代码

     private void StartHttp_Click(object sender, RoutedEventArgs e)
            {
                if (httpServer != null) return;
                httpServer = new HttpListener();
                httpServer.AuthenticationSchemes = AuthenticationSchemes.Anonymous;
                httpServer.Prefixes.Add("http://localhost:"+portText.Text+"/");
                
                httpServer.Start();
                Debug.WriteLine("启用http监听!");
                httpServer.BeginGetContext(Read, httpServer);
            }
    
    

    读取http请求代码,有两个方法,都测试了,浏览器页面都显示400错误

       private  void Read(IAsyncResult result)
            {
                ///获取到请求
                HttpListenerContext context = this.httpServer.EndGetContext(result);
                ///获取请求的数据
                HttpListenerRequest request = context.Request;
                string contentType = request.ContentType;
                string httpMethod = request.HttpMethod;
                string userAgent = request.UserAgent;
                StreamReader sr = new StreamReader(request.InputStream);
                string code = sr.ReadToEnd();
                Debug.WriteLine("收到数据:" + code);
                ///返回数据
                byte[] bys = Encoding.UTF8.GetBytes(DateTime.Now.ToString());
                context.Response.OutputStream.Write(bys, 0, bys.Length);
                context.Response.Close();
                this.httpServer.BeginGetContext(this.Read, this.httpServer);
            }
    
            private void ListenerHandle(IAsyncResult result)
            {
                try
                {
                    httpServer = result.AsyncState as HttpListener;
                    if (httpServer.IsListening)
                    {
                        httpServer.BeginGetContext(ListenerHandle, result);
                        HttpListenerContext context = httpServer.EndGetContext(result);
                        //解析Request请求
                        HttpListenerRequest request = context.Request;
                        string content = "";
                        switch (request.HttpMethod)
                        {
                            case "POST":
                                {
                                    Stream stream = context.Request.InputStream;
                                    StreamReader reader = new StreamReader(stream, Encoding.UTF8);
                                    content = reader.ReadToEnd();
                                }
                                break;
                            case "GET":
                                {
                                    var data = request.QueryString;
                                }
                                break;
                        }
             
                        Debug.WriteLine("收到数据:" + content);
                        testText.Text += "\n" + content;
                        //构造Response响应
                        HttpListenerResponse response = context.Response;
                        response.StatusCode = 200;
                        response.ContentType = "application/json;charset=UTF-8";
                        response.ContentEncoding = Encoding.UTF8;
                        response.AppendHeader("Content-Type", "application/json;charset=UTF-8");
    
                        using (StreamWriter writer = new StreamWriter(response.OutputStream, Encoding.UTF8))
                        {
                            writer.Write("");
                            writer.Close();
                            response.Close();
                        }
                    }
    
                }
                catch (Exception ex)
                {
                    testText.Text += "\n" + ex.Message;
                    Debug.WriteLine("收到数据:" + ex.Message);
                }
            }

    如何解决这个问题?或者说怎么能让浏览器或telnet访问迷你http服务器成功,返回后台输出的字符串?

    2020年5月1日 11:34

答案

  • Hi Trian55,

    你可以尝试以下代码来实现httplistener的简单使用,相关的代码我已经写了注释,你可以看下。

    static void Main(string[] args)
            {
                // 检查系统是否支持
                if (!HttpListener.IsSupported)
                {
                    throw new System.InvalidOperationException(
                        "使用 HttpListener 必须为 Windows XP SP2 或 Server 2003 以上系统!");
                }
                // 注意前缀必须以 / 正斜杠结尾
                string[] prefixes = new string[] { "http://localhost:9090/1.htm/" };
                // 创建监听器.
                HttpListener listener = new HttpListener();
                // 增加监听的前缀.
                foreach (string s in prefixes)
                {
                    listener.Prefixes.Add(s);
                }
                // 开始监听
                listener.Start();
                Console.WriteLine("监听中...");
                while (true)
                {
                    // 注意: GetContext 方法将阻塞线程,直到请求到达
                    HttpListenerContext context = listener.GetContext();
                    // 取得请求对象
                    HttpListenerRequest request = context.Request;
                    Console.WriteLine("{0} {1} HTTP/1.1", request.HttpMethod, request.RawUrl);
                    Console.WriteLine("Accept: {0}", string.Join(",", request.AcceptTypes));
                    Console.WriteLine("Accept-Language: {0}",
                        string.Join(",", request.UserLanguages));
                    Console.WriteLine("User-Agent: {0}", request.UserAgent);
                    Console.WriteLine("Accept-Encoding: {0}", request.Headers["Accept-Encoding"]);
                    Console.WriteLine("Connection: {0}",
                        request.KeepAlive ? "Keep-Alive" : "close");
                    Console.WriteLine("Host: {0}", request.UserHostName);
                    Console.WriteLine("Pragma: {0}", request.Headers["Pragma"]);
                    // 取得回应对象
                    HttpListenerResponse response = context.Response;
                    // 构造回应内容
                    string responseString
                        = @"<html>
                    <head><title>From HttpListener Server</title></head>
                    <body><h1>Hello, world.</h1></body>
                </html>";
                    // 设置回应头部内容,长度,编码
                    response.ContentLength64
                        = System.Text.Encoding.UTF8.GetByteCount(responseString);
                    response.ContentType = "text/html; charset=UTF-8";
                    // 输出回应内容
                    System.IO.Stream output = response.OutputStream;
                    System.IO.StreamWriter writer = new System.IO.StreamWriter(output);
                    writer.Write(responseString);
                    // 必须关闭输出流
                    writer.Close();
    
                    if (Console.KeyAvailable)
                        break;
                }
                // 关闭服务器
                listener.Stop();
            }

    这里我的程序是必须要以管理员权限进行的,另外我再说下httplistener的简单的使用,httplistener是在网页打开后运行程序,如果监测到了,就返回一些基本数据,我做的这个是成功监测到后原始的网页会发生改变,变成Hello, world界面网页。

    你可以先尝试下我的代码,如果有其他问题,你可以再问我。

    这也是官方文档中Httplistener使用的方法:

    HttpListener Class

    Best Regards,

    Jack


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.


    2020年5月5日 6:58
    版主