HttpListener:请求的地址在此上下文中无效

2024-02-23

当创建一个HttpListener对象使用

var server = new HttpListener();
server.Prefixes.Add("http://*:8080/");
server.Start();

一切正常。但是,当我使用

var server = new HttpListener();
server.Prefixes.Add("http://demindiro.com:8080/");
server.Start();

它抛出System.Net.Sockets.SocketException (0x80004005): The requested address is not valid in this context(下面是完整的堆栈跟踪)。

在谷歌上搜索异常后,很明显它与所使用的地址有关。深入挖掘后Mono源代码Http监听器 https://github.com/mono/mono/blob/master/mcs/class/System/System.Net/HttpListener.cs and 端点管理器 https://github.com/mono/mono/blob/master/mcs/class/System/System.Net/EndPointManager.cs我确定问题可能出在这部分代码中(位于获取EP监听器 https://github.com/mono/mono/blob/7e7d8a3b4fccfaca91ef74b963f495c704e07085/mcs/class/System/System.Net/EndPointManager.cs#L80-L97):

static EndPointListener GetEPListener (string host, int port, HttpListener listener, bool secure)
{
    IPAddress addr;
    if (host == "*")
        addr = IPAddress.Any;
    else if (IPAddress.TryParse(host, out addr) == false){
        try {
#pragma warning disable 618
            IPHostEntry iphost = Dns.GetHostByName(host);
#pragma warning restore 618
            if (iphost != null)
                addr = iphost.AddressList[0]; // <---
            else
                addr = IPAddress.Any;
        } catch {
            addr = IPAddress.Any;
        }
        // ...    
    }

我发现几乎在所有情况下ÌPAddress.Any除非它可以将外部 IP 地址与给定的主机名关联起来,否则会使用它。

然而,我只能假设这是故意的,因为它是相当明确地写的,而且看起来HttpListener对于其他开发人员来说工作得很好,所以在这一点上,我对这里出了什么问题一无所知。


Stacktrace:
Unhandled Exception:
System.Net.Sockets.SocketException (0x80004005): The requested address is not valid in this context
  at System.Net.Sockets.Socket.Bind (System.Net.EndPoint localEP) [0x00043] in <50d80b08c1a5449282b22aedf03ce925>:0 
  at System.Net.EndPointListener..ctor (System.Net.HttpListener listener, System.Net.IPAddress addr, System.Int32 port, System.Boolean secure) [0x00047] in <50d80b08c1a5449282b22aedf03ce925>:0 
  at System.Net.EndPointManager.GetEPListener (System.String host, System.Int32 port, System.Net.HttpListener listener, System.Boolean secure) [0x0009d] in <50d80b08c1a5449282b22aedf03ce925>:0 
  at System.Net.EndPointManager.AddPrefixInternal (System.String p, System.Net.HttpListener listener) [0x0005e] in <50d80b08c1a5449282b22aedf03ce925>:0 
  at System.Net.EndPointManager.AddListener (System.Net.HttpListener listener) [0x0009c] in <50d80b08c1a5449282b22aedf03ce925>:0 
  at System.Net.HttpListener.Start () [0x0000f] in <50d80b08c1a5449282b22aedf03ce925>:0 
  at Playground.Playground.StartHttpListener () [0x00016] in <d51cc6c047ee47c9a05c5e174876cbec>:0 
  at Playground.Playground.Main (System.String[] args) [0x00000] in <d51cc6c047ee47c9a05c5e174876cbec>:0 
[ERROR] FATAL UNHANDLED EXCEPTION: System.Net.Sockets.SocketException (0x80004005): The requested address is not valid in this context
  at System.Net.Sockets.Socket.Bind (System.Net.EndPoint localEP) [0x00043] in <50d80b08c1a5449282b22aedf03ce925>:0 
  at System.Net.EndPointListener..ctor (System.Net.HttpListener listener, System.Net.IPAddress addr, System.Int32 port, System.Boolean secure) [0x00047] in <50d80b08c1a5449282b22aedf03ce925>:0 
  at System.Net.EndPointManager.GetEPListener (System.String host, System.Int32 port, System.Net.HttpListener listener, System.Boolean secure) [0x0009d] in <50d80b08c1a5449282b22aedf03ce925>:0 
  at System.Net.EndPointManager.AddPrefixInternal (System.String p, System.Net.HttpListener listener) [0x0005e] in <50d80b08c1a5449282b22aedf03ce925>:0 
  at System.Net.EndPointManager.AddListener (System.Net.HttpListener listener) [0x0009c] in <50d80b08c1a5449282b22aedf03ce925>:0 
  at System.Net.HttpListener.Start () [0x0000f] in <50d80b08c1a5449282b22aedf03ce925>:0 
  at Playground.Playground.StartHttpListener () [0x00016] in <d51cc6c047ee47c9a05c5e174876cbec>:0 
  at Playground.Playground.Main (System.String[] args) [0x00000] in <d51cc6c047ee47c9a05c5e174876cbec>:0

PS:我明确想使用demindiro.com, not *.

PS2:我知道有很多关于这个特殊例外的主题,但似乎没有一个涉及HttpListener.Start()抛出这个异常。


UPDATE我再次用谷歌搜索了我的问题,但这次我专门寻找TcpListener我找到了这个答案:https://stackoverflow.com/a/17092670/7327379 https://stackoverflow.com/a/17092670/7327379

TcpListener 只能绑定到运行它的计算机的本地 IP 地址。所以你指定的IP不是本地机器的IP。您的公共 IP 与本地计算机的 IP 不同,尤其是当您使用某种 NAT 时。

如果我没记错的话,通常只使用 IPAddress.Any 作为您的 IP 来初始化侦听器。

因此,如果我明白这一点,这意味着要绑定到我的外部 IP,我必须以某种方式从这里开始

Server <-- local IP --> Modem <-- external IP --> The Internet

to this

Server <-- external IP --> The Internet

它是否正确?如果是,如何在没有调制解调器的情况下将服务器连接到互联网?或者我还应该做什么?


考虑到http://demindiro.com http://demindiro.com似乎有效,这可能是多余的。然而...

您需要注意以下几点:

通过主机名绑定不好

一般来说,通过主机名进行绑定是一个坏主意™。如果主机名解析为多个地址 -localhost例如,当您启用了 IPv6,或者当您在同一台计算机上有多个 IPv4 地址时,等等 - 您无法控制它绑定到哪个地址。如果是localhost你可能会(有时不愉快地)惊讶地发现它绑定到::1但不是127.0.0.1.

然而这里的问题是demindiro.com是无法解析为计算机上存在的内部 IP 地址的名称,因此您无法直接绑定到它。准确地说,demindiro.com是(通过 DNS)解析为 IPv4 地址的主机名109.132.169.132(几乎可以肯定)这不是您计算机拥有的 IP 地址。

绑定到主机名并不绑定到主机名

相反,它绑定到主机名在计算机上解析的第一个 IP 地址。不多也不少。

假设您修改了主机文件以具有demindiro.com解析(仅在您的计算机上)为有效的本地 IPv4 地址,例如192.168.0.123。如果我在您的网络上并且连接到该地址,我就可以获得您的服务。无论我尝试访问什么主机名,只要它解析为该地址,我就能获得连接。我可以通过 IP 或解析为该 IP 的任何主机名直接连接,而您永远不会知道。

只有在建立连接并且解析请求之后,您才能(有时)检测哪个主机名是请求的目标。

对于 HTTP(S) 请求,主机名通常作为请求的一部分发送。这允许网络服务器在同一地址上托管多个站点。 Web 服务器接收请求,找出应在本地站点中路由的位置,然后将请求发送到已解析的站点。在 HTTPS 中做到这一点有点困难,但是这个问题主要通过以下方法解决:SNI https://en.wikipedia.org/wiki/Server_Name_Indication.

但是,如果我使用没有主机名的绝对路径向您的服务发出 HTTP 1.0 请求...然后呢?

绑定只能是本地的

换句话说,您无法绑定到运行代码的计算机上不存在的地址。更重要的是,您不能直接绑定到互联网连接的公共地址,除非它直接在您的计算机上终止。由于我们中没有多少人运行拨号或桥接 PPPoE 到我们的桌面,因此您尝试绑定的地址可能不可用。

一般来说,您需要做的是在 Internet 连接上设置某种 NAT 重定向,以将端口 8080 上的传入请求转换为公共地址109.132.169.132并将它们重定向到您的内部地址(192.168.0.123管他呢)。

那是假设demindiro.com解析为您的公共 IP 地址。如果没有,那么你就会遇到各种各样的其他问题。跨公共网络的 NAT 很奇怪。您在链中添加的每个 NAT 都会增加更多的复杂性、更多的故障点等。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

HttpListener:请求的地址在此上下文中无效 的相关文章

随机推荐

  • MVC4 FoolProof 数据注释 - 如何检查该字段不等于零?

    我正在尝试使用 MVC Foolproof 库来验证我的模型并分别显示错误消息 但是 当我使用万无一失的验证时 单击提交按钮时 即使常规验证也不会显示 我的要求是我有一个数字文本框 它不应该为空或零 文本框值是根据从前面的下拉列表中选择的值
  • 如何将变量从控制器传递到视图 joomla mvc

    根据此示例 如何将变量从 joomla 子控制器传递到视图 class MYControllerControllerParser extends JController public function construct default a
  • 如何仅序列化.Net 中的某些属性?

    这是一个 Web 项目 所以我有几个继承自 Web UI 的类 我只想序列化非常特殊的属性 基本上 只有本地属性 我知道 XMLIgnore 属性可以放置在属性上以忽略项目 但这在我的上下文中不起作用 因为这需要修改一堆我真的不想修改的东西
  • 使用 Woocommerce 中的元查询从任何地方排除特定产品

    我想从我的商店页面以及我的主页中排除来自给定城市的产品 在主页中我显示来自 flatsome UX Builder 的 woocommerce 商店小部件 不确定它是一个小部件 的产品 给定城市的产品不会出现在我的商店页面中 但它们仍然出现
  • 如何在 Flutter 中将数据从子 Stateful widget 传递到 Parent Widget

    我的 flutter 应用程序中有一个有状态的小部件 DayPicker 相同的代码是 class DayPicker extends StatefulWidget override DayPickerState createState g
  • 分布式 ASP.Net 状态服务

    我想知道是否存在任何分布式 ASP Net State Service 替代方案 Session 可以存储在 InProc StateService 或 SQL 中 您还可以编写自定义存储提供程序 对于负载平衡 没有任何形式的粘性 IP 只
  • json 模式中的对象重用和组合

    我有一个 json blob 看起来像这样 ObjectA Object1 fields Object2 fields Object3 fields ObjectB Object1 fields Object2 fields Object3
  • srand (time (null)) 导致编译器警告:隐式转换丢失整数精度

    如果这个问题已经得到解答 我们深表歉意 include
  • ASP.net Bin目录-dll加载

    我需要在我的 asp net 应用程序中使用 dll 如何加载不是来自 bin 目录的 dll 也许我应该提到该应用程序是 asp 代码和 asp net 代码的混合体 所以 当我在我的机器上开发它时 我在 bin 目录中放置了一个 dll
  • 将 JSX 转换为 JSON 或 String,然后再转换回来

    我想将 React 组件的状态保存在数据库中 Json stringify myComponent 但是 当我尝试通过 JSON parse 再次使用该组件时 我得到了 Error Objects are not valid as a Re
  • 如何更改 Mac 上的 JAR 图标?

    我的 Mac 上有一个名为 Test jar 的 JAR 文件 当我单击它时 该文件运行得非常好 它所做的只是打开一个小窗口 并显示 Test 所以它是一个简单的应用程序 我是 Java 编程新手 我的问题是如何将 jar 文件的图标更改为
  • C# 二进制常量表示

    我真的被这个难住了 在C 中 有如下的十六进制常量表示格式 int a 0xAF2323F5 有二进制常量表示格式吗 不 C 中没有二进制文字 您当然可以使用 Convert ToInt32 解析二进制格式的字符串 但我认为这不是一个很好的
  • 如何在 Python 中将*所有*字符转义为相应的 html 实体名称和数字?

    我想将字符串编码为其相应的 html 实体 但不幸的是我无法做到 正如我在问题标题中所说 我想要all字符串中的字符将被转换为相应的 html 实体 数字和名称 所以根据文档 https docs python org 3 library
  • 如何在 firestore 文档 ID 的位置添加用户 UID

    我正在尝试获取用户 UID 来代替 Firebase Firestore 中自动生成的文档 ID 但由于此错误而无法获取它 类型错误 firebase auth currentUser 为 null 这是我的 index js 文件 Fir
  • Python请求访问OAUTH网站内容 - SNL财经

    我一直在用头撞墙 试图从新闻来源 SNL 财经 检索内容 我拥有有效的凭据 因此理论上我应该能够以编程方式访问他们的新闻内容 简而言之 我尝试执行以下脚本但没有成功 s requests Session client id client s
  • 谷歌地图 API v3 的服务器端集群

    我目前正在开发一种谷歌地图概述小部件 它将位置显示为地图上的标记 标记的数量从数百个到数千个 10000 个以上 不等 现在我正在使用谷歌地图的 MarkerClusterer v3 1 0和谷歌地图 javascript api v3 高
  • 如何给JTextField添加背景图片?

    我知道如何向 JPanel 添加背景图像 创建扩展 JPanel 的 ImagePanel 类并重载它的 PaintComponent 方法 但是 JTextField 的这个技巧无法正常工作 显示图像 但不显示文本 那么 如何正确地向 J
  • Multiprocessing.pool 具有多个 args 和 kwargs 的函数

    我想使用 mutliprocessing pool 方法并行计算 问题是我想在计算中使用的函数提供了两个参数和可选的 kwargs 第一个参数是数据帧 第二个参数是 str 任何 kwargs 是字典 对于我尝试执行的所有计算 我想要使用的
  • 如何在 swift 中导入 JSQMessagesViewController?

    我正在使用 xcode 6 3 swift 1 2 并使用 cocoapods 安装 JSQMessagesViewController 库 这是我的 pod 文件 pod JSQMessagesViewController 和我的桥接文件
  • HttpListener:请求的地址在此上下文中无效

    当创建一个HttpListener对象使用 var server new HttpListener server Prefixes Add http 8080 server Start 一切正常 但是 当我使用 var server new