溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Kestrel中ListenAnyIP和ListenLocalhost的區(qū)別是什么

發(fā)布時間:2021-07-09 17:22:54 來源:億速云 閱讀:245 作者:Leah 欄目:大數(shù)據(jù)

Kestrel中ListenAnyIP和ListenLocalhost的區(qū)別是什么,相信很多沒有經(jīng)驗的人對此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個問題。


本地回環(huán)地址(Loopback Address):

百度定義的定義,127.0.0.1,通常被稱為本地回環(huán)地址(Loopback Address),不屬于任何一個有類別地址類。它代表設(shè)備的本地虛擬接口,所以默認(rèn)被看作是永遠(yuǎn)不會宕掉的接口。在Windows操作系統(tǒng)中也有相似的定義,所以通常在安裝網(wǎng)卡前就可以ping通這個本地回環(huán)地址。一般都會用來檢查本地網(wǎng)絡(luò)協(xié)議、基本數(shù)據(jù)接口等是否正常的。

IPv6的本地回環(huán)地址形式:0:0:0:0:0:0:0:1,同IPV4中127.0.0.1地址的含義一樣,表示節(jié)點(diǎn)自已,也可以是::1,大多數(shù)windows和linux電腦上都將localhost指向了127.0.0.1這個地址,相當(dāng)于是本機(jī)地址。

ip地址類型

公有地址

公有地址(Public address)由Inter NIC(Internet Network Information Center因特網(wǎng)信息中心)負(fù)責(zé)。這些IP地址分配給注冊并向Inter NIC提出申請的組織機(jī)構(gòu)。通過它直接訪問因特網(wǎng)。

私有地址

私有地址(Private address)屬于非注冊地址,專門為組織機(jī)構(gòu)內(nèi)部使用。以下列出留用的內(nèi)部私有地址

  • 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 含義:

維基百科解釋,表示無效的,未知,不可用的目標(biāo)

服務(wù)器中,常常表示監(jiān)聽本機(jī)所有的ip地址。一般我們在服務(wù)端綁定端口的時候可以選擇綁定到0.0.0.0,這樣就可以通過多個ip地址訪問我的服務(wù)。

ListenLocalhost 和ListenAnyIP 區(qū)別

通過編碼配置Kestrel監(jiān)聽端口有三個方法可以實(shí)現(xiàn)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);
       }

通過源碼我們可以發(fā)現(xiàn),他們之間的區(qū)別是在構(gòu)造listenopthons對象不同,分別使用LocalhostListenOptions和AnyIPListenOptions進(jìn)行new創(chuàng)建實(shí)例,而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);
           }
       }

       //綁定回環(huán)地址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());
       }

     
   }
 internal sealed class AnyIPListenOptions : ListenOptions
   {
       internal AnyIPListenOptions(int port)
           : base(new IPEndPoint(IPAddress.IPv6Any, port))
       {
       }

       //如果本機(jī)不支持 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);
           }
       }
   }

小結(jié):通過以上分析,端口綁定時,建議使用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);
                   });

看完上述內(nèi)容,你們掌握Kestrel中ListenAnyIP和ListenLocalhost的區(qū)別是什么的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI