问题

在上篇文章,把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 两个方法的源码

/// <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);}
    /// <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方法。源码如下:

  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是::1internal 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());}}
 internal sealed class AnyIPListenOptions : ListenOptions{internal AnyIPListenOptions(int port): base(new IPEndPoint(IPAddress.IPv6Any, port)){}//如果本机不支持 IPv6就绑定ipv4internal 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 IPv6EndPoint = new IPEndPoint(IPAddress.Any, IPEndPoint.Port);await base.BindAsync(context).ConfigureAwait(false);}}}

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

 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

Kestrel的ListenAnyIP和ListenLocalhost的区别相关推荐

  1. 什么是Asp.net Core?和 .net core有什么区别?

    为什么要写这篇文章 写这篇文章有两个原因,第一个是因为新站点创建出来后一直空置着,所以写一篇文章放在这里.第二就是因为近来在做一些基于Asp.net core平台的项目开发,也遇到了一些问题,正好趁此 ...

  2. 深入理解kestrel的应用

    1 前言 之所以写本文章,是因为在我停止维护多年前写的NetworkSocket组件两年多来,还是有一些开发者在关注这个项目,我希望有类似需求的开发者明白为什么要停止更新,可以使用什么更好的方式来替换 ...

  3. 什么是Asp.net Core?和 .net core有什么区别?(转)

    什么是Asp.Net core 我相信很多C# Developer已经对于.net core不算陌生了,就算没有正式使用相信也应该有所了解.微软在推出来.net core的同时为了方便一些原有的项目可 ...

  4. C# 什么是Asp.net Core?和 .net core有什么区别?

     本章全部摘自什么是Asp.net Core?和 .net core有什么区别? ,做加深记忆用 为什么要写这篇文章  写这篇文章有两个原因,第一个是因为新站点创建出来后一直空置着,所以写一篇文章放在 ...

  5. java与jdk版本号的区别

    Java是面向对象的编程语言,在我们开发Java应用的程序员的专业术语里,Java这个单词其实指的是Java开发工具,也就是JDK(Java Development Kit).所以我们常常在CSDN等 ...

  6. kestrel服务器性能,深入理解kestrel的应用

    原标题:深入理解kestrel的应用 1 前言 之所以写本文章,是因为在我停止维护多年前写的NetworkSocket组件两年多来,还是有一些开发者在关注这个项目,我希望有类似需求的开发者明白为什么要 ...

  7. 在.NET 6.0上使用Kestrel配置和自定义HTTPS

    本章是<定制ASP NET 6.0框架系列文章>的第四篇.在本章,我们将学习ASP.NET Core的Kestrel配置和自定义HTTPS,好我们开始正文. 在ASP.NET Core中, ...

  8. ASP.NET Core 托管和部署(一)【Kestrel】

    ASP.NET Core 中的 Kestrel Web 服务器实现 ASP.NET Core 中的 Kestrel Web 服务器实现 Kestrel 是一个跨平台的适用于 ASP.NET Core ...

  9. RPC 笔记(01)— RPC概念、调用流程、RPC 与 Restful API 区别

    1. 基本概念 PRC 远程过程调用 Remote Procedure Call,其就是一个节点请求另外一个节点提供的服务.当两个物理分离的子系统需要建立逻辑上的关联时,RPC 是牵线搭桥的常见技术手 ...

最新文章

  1. spring cloud gateway之服务注册与发现
  2. ICLR2020放榜 687篇入选34篇得满分! 且看OpenReview数据图文详解
  3. 通过FFT来计算螺旋线的匝数
  4. CSocket类的使用
  5. 【转】DB2学习路线
  6. 如何用AD20打开ddb文件
  7. js中判断对象数据类型的方法
  8. Go语言标准库之strconv
  9. C语言 mallocfree
  10. 【二分法】计蒜客:二分答案
  11. Uva 10557 XYZZY
  12. python找不到指定的路径_[Python学习]错误篇二:切换当前工作目录时出错——FileNotFoundError: [WinError 3] 系统找不到指定的路径...
  13. 关联分析中FPGrowth算法原理及实战
  14. C2. Skyscrapers (hard version)(单调栈、dp)
  15. 《电路原理》清华公开课 week1 支路变量、元件、KCL、KVL
  16. Opencv学习之:如何将矩阵转换成图片,如何将图片转换成矩阵
  17. pycharm快捷键及中文说明【使用翻译工具一条一条翻译】
  18. mac下如何连续看图
  19. HTML CSS笔记(没有基础内容,比如br标签是换行什么的),CSS2.1,CSS3,响应式布局
  20. PDF 阅读与注释的实践——知之阅读、Markdown+Git、Kami、Edge、Mendeley、Zotero

热门文章

  1. C语言中递归什么时候能够省略return引发的思考:通过内联汇编解读C语言函数return的本质...
  2. 1.2开发文档简读,了解全貌.mp4
  3. JIL 编译与 AOT 编译
  4. 查看MySQL的当前日期
  5. 【转】R语言 RStudio快捷键
  6. 隐藏UITableView当没有数据或数据不够的时候出现的分割线.
  7. [Forward] 因为火炬,所以迟到,工资照扣
  8. apache2 配置php,Windows配置PHP5与Apache2
  9. Django中session和cookie简单的使用
  10. Git vs SVN