首页 > 解决方案 > HttpListener 不使用显式前缀但使用模式前缀

问题描述

我有一个简单的 C# HttpListener (System.Net) 应用程序,代码如下,除了获取请求之外什么都不做,在控制台上打印请求 URL,并以简单的 JSON 消息进行响应。(请参阅下面的代码。)我的问题是侦听器应用程序没有捕获显式前缀的消息,而是捕获它们的模式前缀。

我的环境:带有目标框架 .Net 5.0 的 C#,内置于 Visual Studio 2019。主机/目标系统是名为“raspberrypi3b”的 Raspberry Pi 3B。我有另一台 PC 用来向 Raspberry Pi 主机发出请求。

情况是这样的:

  1. 请求“http://localhost:8080/testing”在从 Raspberry Pi 发送到自身时有效。控制台上打印的 URL 是“http://localhost:8080/testing”。
  2. 请求“http://raspberrypi3b:8080/testing”在从 Raspberry Pi 发送到自身时也有效。控制台上打印的 URL 是“http://raspberrypi3b:8080/testing”。
  3. 但是,从我的客户端 PC 发送请求“http://raspberrypi3b:8080/testing”时不起作用。(浏览器错误是“raspberrypi3b 拒绝连接”。)

但是...如果我将代码中的前缀“http://raspberrypi3b:8080/”更改为“http://*:8000/”,上面的场景 3 就可以了。请求上打印的 URL 是“http://raspberrypi3b:8080”,这是我认为我试图用显式前缀捕获的。

那么为什么客户端请求“http://raspberrypi3b/testing”不能使用显式前缀“http://raspberrypi3b:8000/”但使用模式前缀“http://*:8000/”却可以正常工作?

using System;
using System.Net;
using System.Text;

namespace Listen {

    class Program {

        static void Main(string[] args) {
            var listener = new HttpListener();
            listener.Prefixes.Add("http://localhost:8000/");
            listener.Prefixes.Add("http://raspberrypi3b:8000/"); // doesn't work from remote client
            //listener.Prefixes.Add("http://*:8000/"); // replace above line with this and it works fine from remote client
            listener.Start();
            listener.BeginGetContext(new AsyncCallback(GetContextCallback), listener);
            Console.WriteLine("Press Enter to stop...");
            Console.ReadLine();
        }

        static void GetContextCallback(IAsyncResult result) {
            var myListener = (HttpListener)result.AsyncState;
            var myContext = myListener.EndGetContext(result);
            Console.WriteLine("Received request '" + myContext.Request.Url + "'.");
            var answer = Encoding.UTF8.GetBytes("{ \"status\": \"ok\" }");
            myContext.Response.ContentType = "application/json";
            myContext.Response.ContentLength64 = answer.Length;
            myContext.Response.OutputStream.Write(answer, 0, answer.Length);
            myContext.Response.OutputStream.Close();
            myListener.BeginGetContext(new AsyncCallback(GetContextCallback), myListener);
        }

    }

}

标签: c#.netraspberry-pihttplistener

解决方案


推荐阅读