您好,登錄后才能下訂單哦!
Kestrel中ListenAnyIP和ListenLocalhost的區別是什么,相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。
本地回環地址(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地址訪問我的服務。
通過編碼配置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是::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))
{
}
//如果本機不支持 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地址。
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);
});
看完上述內容,你們掌握Kestrel中ListenAnyIP和ListenLocalhost的區別是什么的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。