前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >Kestrel的ListenAnyIP和ListenLocalhost的区别

Kestrel的ListenAnyIP和ListenLocalhost的区别

作者头像
李明成
发布于 2020-08-04 08:35:11
发布于 2020-08-04 08:35:11
71900
代码可运行
举报
文章被收录于专栏:dotNET知音dotNET知音
运行总次数:0
代码可运行
问题

在上篇文章,把AAStore.ProductCatalog.Api部署到docker中运行,输入地址访问报错如下图,说明外部无法访问这个url。(当然本地开发环境测试是可以访问的)。后来修改此处options.ListenLocalhost(8081)的代码改成options.ListenAnyIP(8081),可以访问了。那这两种写法有什么区别呢?

在区别之前,我们先熟悉几个概念(如果网络知识比较好的,可以跳过):

本地回环地址(Loopback Address):

百度定义的定义,127.0.0.1,通常被称为本地回环地址(Loopback Address),不属于任何一个有类别地址类。它代表设备的本地虚拟接口,所以默认被看作是永远不会宕掉的接口。在Windows操作系统中也有相似的定义,所以通常在安装网卡前就可以ping通这个本地回环地址。一般都会用来检查本地网络协议、基本数据接口等是否正常的。

IPv6的本地回环地址形式:0:0:0:0:0:0:0:1,同IPV4中127.0.0.1地址的含义一样,表示节点自已,也可以是::1,大多数windows和linux电脑上都将localhost指向了127.0.0.1这个地址,相当于是本机地址。

ip地址类型

公有地址

公有地址(Public address)由Inter NIC(Internet Network Information Center因特网信息中心)负责。这些IP地址分配给注册并向Inter NIC提出申请的组织机构。通过它直接访问因特网。

私有地址

私有地址(Private address)属于非注册地址,专门为组织机构内部使用。以下列出留用的内部私有地址

  • A类 10.0.0.0--10.255.255.255
  • B类 172.16.0.0--172.31.255.255
  • C类 192.168.0.0--192.168.255.255

IPv6 [::] ( 0000:0000:0000:0000:0000:0000:0000:0000的简写), IPv4 0.0.0.0 含义:

维基百科解释,表示无效的,未知,不可用的目标

服务器中,常常表示监听本机所有的ip地址。一般我们在服务端绑定端口的时候可以选择绑定到0.0.0.0,这样就可以通过多个ip地址访问我的服务。

ListenLocalhost 和ListenAnyIP 区别

通过编码配置Kestrel监听端口有三个方法可以实现ListenLocalhost、ListenAnyIP、Listen,其中ListenLocalhost等同于Listen的IPAddress.IPv6Loopback 和IPAddress.Loopback,ListenAnyIP等同于Listen的IPAddress.IPv6Any和IPAddress.Any。下面我看看可以查看他们的源代码。

ListenLocalhost、ListenAnyIP 两个方法的源码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制

        /// <summary>
        /// Listens on ::1 and 127.0.0.1 with the given port. Requesting a dynamic port by specifying 0 is not supported
        /// for this type of endpoint.
        /// </summary>
        public void ListenLocalhost(int port, Action<ListenOptions> configure)
        {
            if (configure == null)
            {
                throw new ArgumentNullException(nameof(configure));
            }

            var listenOptions = new LocalhostListenOptions(port);
            ApplyEndpointDefaults(listenOptions);
            configure(listenOptions);
            ListenOptions.Add(listenOptions);
        }
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    /// <summary>
        /// Listens on all IPs using IPv6 [::], or IPv4 0.0.0.0 if IPv6 is not supported.
        /// </summary>
        public void ListenAnyIP(int port, Action<ListenOptions> configure)
        {
            if (configure == null)
            {
                throw new ArgumentNullException(nameof(configure));
            }

            var listenOptions = new AnyIPListenOptions(port);
            ApplyEndpointDefaults(listenOptions);
            configure(listenOptions);
            ListenOptions.Add(listenOptions);
        }

通过源码我们可以发现,他们之间的区别是在构造listenopthons对象不同,分别使用LocalhostListenOptions和AnyIPListenOptions进行new创建实例,而AnyIPListenOptions和LocalhostListenOptions都继承类ListenOptions,并且重写BindAsync方法。源码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
  internal sealed class LocalhostListenOptions : ListenOptions
    {
        internal LocalhostListenOptions(int port)
            : base(new IPEndPoint(IPAddress.Loopback, port))
        {
            if (port == 0)
            {
                throw new InvalidOperationException(CoreStrings.DynamicPortOnLocalhostNotSupported);
            }
        }

        //绑定回环地址ipv4是127.0.0.1 ,iPV6是::1
        internal override async Task BindAsync(AddressBindContext context)
        {
            var exceptions = new List<Exception>();

            try
            {
                var v4Options = Clone(IPAddress.Loopback);
                await AddressBinder.BindEndpointAsync(v4Options, context).ConfigureAwait(false);
            }
            catch (Exception ex) when (!(ex is IOException))
            {
                context.Logger.LogWarning(0, CoreStrings.NetworkInterfaceBindingFailed, GetDisplayName(), "IPv4 loopback", ex.Message);
                exceptions.Add(ex);
            }

            try
            {
                var v6Options = Clone(IPAddress.IPv6Loopback);
                await AddressBinder.BindEndpointAsync(v6Options, context).ConfigureAwait(false);
            }
            catch (Exception ex) when (!(ex is IOException))
            {
                context.Logger.LogWarning(0, CoreStrings.NetworkInterfaceBindingFailed, GetDisplayName(), "IPv6 loopback", ex.Message);
                exceptions.Add(ex);
            }

            if (exceptions.Count == 2)
            {
                throw new IOException(CoreStrings.FormatAddressBindingFailed(GetDisplayName()), new AggregateException(exceptions));
            }

            // If StartLocalhost doesn't throw, there is at least one listener.
            // The port cannot change for "localhost".
            context.Addresses.Add(GetDisplayName());
        }

      
    }
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 internal sealed class AnyIPListenOptions : ListenOptions
    {
        internal AnyIPListenOptions(int port)
            : base(new IPEndPoint(IPAddress.IPv6Any, port))
        {
        }

        //如果本机不支持 IPv6就绑定ipv4
        internal override async Task BindAsync(AddressBindContext context)
        {
            // when address is 'http://hostname:port', 'http://*:port', or 'http://+:port'
            try
            {
                await base.BindAsync(context).ConfigureAwait(false);
            }
            catch (Exception ex) when (!(ex is IOException))
            {
                context.Logger.LogDebug(CoreStrings.FormatFallbackToIPv4Any(IPEndPoint.Port));

                // for machines that do not support IPv6
                EndPoint = new IPEndPoint(IPAddress.Any, IPEndPoint.Port);
                await base.BindAsync(context).ConfigureAwait(false);
            }
        }
    }

小结:通过以上分析,端口绑定时,建议使用IPAddress.Any,可以支持ipv6和ipv4地址。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 webBuilder.ConfigureKestrel(options =>
                    {
                        //1.ListenLocalhost方法
                        //options.ListenLocalhost(8081);

                        //2.ListenAnyIP方法
                        options.ListenAnyIP(8081);

                        //3.Listen方法
                        // options.Listen(IPAddress.Loopback, 8081);

                        // Setup a HTTP/2 endpoint without TLS.
                        options.ListenAnyIP(18081, o => o.Protocols =
                            HttpProtocols.Http1AndHttp2);
                    });

参考:https://juejin.im/post/5d258b6ae51d454f73356dcf

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-07-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 dotNET知音 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
.NET 云原生架构师训练营(KestrelServer源码分析)--学习笔记
理解 KestrelServer 如何接收网络请求,网络请求如何转换成 http request context(C# 可识别)
郑子铭
2022/01/17
3030
.NET 云原生架构师训练营(KestrelServer源码分析)--学习笔记
KestrelServer详解[1]:注册监听终结点(Endpoint)
具有跨平台能力的KestrelServer是最重要的服务器类型。针对KestrelServer的设置均体现在KestrelServerOptions配置选项上,注册的终结点是它承载的最重要的配置选项。这里所谓的终结点(Endpoint)与“路由”介绍的终结点不是一回事,这里表示的就是服务器在监听请求时绑定的网络地址,对应着一个System.Net.Endpoint对象。我们知道ASP.NET Core应用承载API也提供了注册监听地址的方法,其本质其实也是为了注册终结点,那么两种注册方式如何取舍呢?本文提供的示例演示已经同步到《ASP.NET Core 6框架揭秘-实例演示版》)
蒋金楠
2022/05/09
1.2K0
KestrelServer详解[1]:注册监听终结点(Endpoint)
.NET Core 3.0之深入源码理解Kestrel的集成与应用(一)
ASP.NET Core 的 Web 服务器默认采用Kestrel,这是一个跨平台、轻量级的Web服务器(需要指出的是从 ASP.NET Core 2.1 开始 Kestrel 就不基于 libuv 了 "Starting in ASP.NET Core 2.1.0, managed sockets will be replacing libuv as Kestrel's default transport." 详见 https://github.com/aspnet/Announcements/issues/296)。
AI.NET 极客圈
2019/07/19
1.9K0
asp.net core启动源码以及监听,到处理请求响应的过程
        asp.net core发布至今已经将近6年了,很多人对于这一块还是有些陌生,或者说没接触过;接触过的,对于asp.net core整个启动过程,监听过程,以及请求过程,响应过程也是一知半解,可能有的同学在面试中有被问过整个的启动过程;对此,有个想法就是针对于之前没有接触过core的,后续会持续输出asp.net core方面的基础,包括IOC,中间件,主机,日志,以及服务器,配置,options等方面的入门讲解;本篇博客先粗略的讲解一下,asp.net core整个程序启动过程,以及启动之后都干了什么,我们的请求是如何到达我们的接口的。
陈显达
2022/11/07
2K0
asp.net core启动源码以及监听,到处理请求响应的过程
C# Socket编程 笔记,Socket 详解,入门简单
文章按照 Socket 的 创建、连接、传输数据、释放资源的过程来写。给出方法、参数的详细信息。
痴者工良
2021/04/26
1.4K0
ASP.NET Core部署HTTPS
上面两段代码描述的都是Kestrel服务的option从配置文件中读取 紧接着在startup中增加 app.UseHttpsRedirection(); app.UseHsts();//默认是开启的,如果是,就不用管它 2,在配置文件appsettings.json中增加,这是单独的配置节点 ,其中path,是pfx文件的位置,password是证书的密码,在阿里云申请的证书,下载iis版的就有这两个。
Echo_Wish
2023/11/30
3560
局域网通过端口通讯
使用DatagramSocket代表UDP协议的Socket,DatagramSocket本身只是码头,不维护状态,不能产生IO流,它的唯一作用就是接收和发送数据报,Java使用DatagramPacket来代表数据报,DatagramSocket接收和发送的数据都是通过DatagramPacket对象完成的。
码客说
2023/02/10
1.9K0
局域网通过端口通讯
.NET 云原生架构师训练营(ASP .NET Core 整体概念推演)--学习笔记
ASP .NET Core 其实就是通过 web framework 处理 HTTP 请求并提供 HTTP 响应
郑子铭
2021/12/30
3130
.NET 云原生架构师训练营(ASP .NET Core 整体概念推演)--学习笔记
C# 多线程与线程扫描器
获取本机IP地址 using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.NetworkInformation; using System.Threading; namespace ConsoleApplication1 { class Program { public static List<string> GetLocal
王瑞MVP
2022/12/28
2290
C#的Sockets
在现代软件开发中,网络通信是不可或缺的一部分。C#提供了一套强大的Sockets API,允许开发者进行底层的网络通信编程。本文将深入探讨Sockets的工作原理、使用场景、最佳实践以及一些高级技巧。
Michel_Rolle
2024/10/09
2.6K0
Java中InetAddress的使用(二):获取本机IP地址的正确姿势【享学Java】
本文接着上文的内容,主要解答上文留下的疑问:既然不能使用InetAddress#getLocalHost()直接去获取到本机的IP地址,那么如何破呢?
YourBatman
2020/04/08
17.6K2
回环地址的一点儿破事
作为划水选手,我们肯定会接触过这样一个东西 -> Virtual loopback interface。当我们写的应用/服务想在同一台机器上进行通信的时候,基本都会使用到它。
Cloud-Cloudys
2023/10/21
8370
回环地址的一点儿破事
【愚公系列】2022年11月 数据库-待定勿看
如今对于网络进行实时通讯的要求越来越高,相关于网络进行实时通讯技术应运而生,如WebRTC,QUIC,HTTP3,WebTransport,WebAssembly,WebCodecs等。
愚公搬代码
2022/12/01
4020
【愚公系列】2022年11月 数据库-待定勿看
dotnet 开启 Fiddler 抓包将会让请求 HOST 头被更改
我在写域名备份功能,想要修改请求的 IP 地址,同时又将原有的请求域名带上。实现方法是修改请求的地址,在 HttpRequestMessage 的 Header 上添加 HOST 记录,记录的值就是原有的域名。然而在开启 Fiddler 之后,将会发现实际发出的请求的 HOST 是实际请求的地址
林德熙
2023/04/07
4780
2020年了,再不会Https就老了
合格的web后端程序员,除搬砖技能,还必须会给各种web服务器启用Https,本文结合ASP.NET Core部署模型聊一聊启用Https的方式。
有态度的马甲
2020/04/16
4.2K0
2020年了,再不会Https就老了
Do you kown Asp.Net Core -- 配置Kestrel端口
Kestrel介绍 在Asp.Net Core中,我们的web application 其实是运行在Kestrel服务上,它是一个基于libuv开源的跨平台可运行 Asp.Net Core 的web服务器。 在开发阶段,我们可以直接使用Kestrel服务器用来测试,也可以使用IISExpress。在使用IISExpress其实也需要启动一个Kestrel服务器,通过IISExpress反向代理请求到Kestrel,很多时候我更喜欢使用Kestrel,因为可以实时看到log。 配置端口 在Socket开发中,
脑洞的蜂蜜
2018/02/01
2K0
ipaddress:Python中网络地址的处理
ipaddress库提供了处理IPv4与IPv6网络地址的类。这些类支持验证,查找网络上的地址和主机,以及其他常见的操作。
luckpunk
2023/09/20
3870
ipaddress:Python中网络地址的处理
硬核图解!断网了,还能ping通 127.0.0.1 吗?为什么?
可能看到标题,你就知道答案了,但是你了解背后的原因吗?那如果把 127.0.0.1 换成 0.0.0.0 或 localhost 会怎么样呢?你知道这几个IP有什么区别吗?
9号同学
2021/07/07
9230
硬核图解!断网了,还能ping通 127.0.0.1 吗?为什么?
Docker网络详解
Docker 网络 Docker网络原理 每启动一个Docker 容器,docker 将给docker 容器分配一个ip 只要启动了docker 就会有一个docker0 网络使用的是桥接模式,ev
PayneWu
2020/12/18
4730
Docker网络详解
【docker】搭建一个”联邦宇宙”——Misskey
misskey是一个去中心化微博,你可以搭建自己的实例,也可以加入其他人的实例。经过这两年的发展,夜梦觉得它已经算是一个比较成熟的程序了~
夜梦星尘
2024/08/20
3170
【docker】搭建一个”联邦宇宙”——Misskey
相关推荐
.NET 云原生架构师训练营(KestrelServer源码分析)--学习笔记
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档