开发者

C# System.Net.IPAddress的使用小结

目录
  • 前言
  • 一、IPAddress 是什么?
    • 1. IPAddress 类概述
    • 2. 作用
  • 二、基础用法
    • 1. 创建IPAddress实例
      • 1)从字符串解析 IP 地址
      • 2)从字节数组构造 IP 地址
      • 3)安全解析 IP 地址
    • 2. 特殊IP地址的静态字段
      • 3. 字节数组与IP地址转换
        • 4. IP地址与字符串转换
          • 5. IP地址与整数转换
            • 1)IPv4 地址与整数的转换原理
            • 2)从 IP 地址转换为整数
            • 3)从整数转换为 IP 地址
            • 4)转换须知
          • 6. 获取 IP 地址的二进制形式
            • 7. 判断 IP 地址类型
            • 三、高级用法
              • 1. 与Dns类 配合使用
                • 1)获取本地IP地址
                • 2)解析域名到IP地址
              • 2. 私有地址检测
                • 1)代码示例
                • 2)代码分析
              • 3. 检查 IP 地址是否在子网内
                • 1)代码示例
                • 2)代码分析
              • 4. CIDR 表示法解析
                • 1)解析IP 和 掩码
                • 2) CIDR格式转换(掩码转为CIDR表示)
                • 3)子网掩码计算(CIDR掩码转为IP地址格式)
              • 5. 网络接口处理
                • 6. IPv4与IPv6映射
                • 四、性能优化技巧
                  • 1. 缓存频繁解析的地址
                    • 2. 使用 Span 优化字节操作
                    • 参考资料:

                      前言

                      在网络编程中,IP地址的处理是基础且不可或缺的环节。C#的System.Net.IPAddress类提供了对IP地址(IPv4和IPv6)的封装和操作功能,支持解析、转换、比较等操作。本文将从基础用法到高级技巧,全面解析IPAddress的使用方法。

                      一、IPAddress 是什么?

                      1. IPAddress 类概述

                      System.Net.IPAddress 是.NET中处理IP地址的核心类型,支持IPv4和IPv6地址的各种操作。

                      2. 作用

                      • 地址解析:从字符串、字节数组构造 IPv4/IPv6 地址
                      • 格式转换:地址与整数、二进制格式互转
                      • 网络计算:子网掩码处理、CIDR 表示法支持
                      • 属性验证:判断地址类型(环回地址、私有地址等)

                      二、基础用法

                      1. 创建IPAddress实例

                      1)从字符串解析 IP 地址

                      最常见的方式是从字符串解析 IP 地址,使用 IPAddress.ParseIPAddress.TryParse 方法。

                      // IPv4 解析  
                      IPAddress ipv4 = IPAddress.Parse("192.168.1.1");
                      // IPv6 解析  
                      IPAddress ipv6 = IPAddress.Parse("2001:db8::8a2e:370:7334");
                      // IPv6 解析(支持压缩格式)  
                      IPAddress ipv6 = IPAddress.Parse("2001:db8::1");  
                      

                      2)从字节数组构造 IP 地址

                      // IPv4:4字节数组  
                      byte[] bytesv4 = { 192, 168, 1, 1 };  
                      IPAddress ipFromBytesV4 = new IPAddress(bytesv4);  
                      
                      // IPv6:16字节数组  
                      byte[] bytesv6 = new byte[16];  
                      new Random().NextBytes(bytesv6);  
                      IPAddress ipFromBytesV6 = new IPAddress(bytesv6);  
                      
                      // IPv6带范围ID(Windows专用)
                      var ipv6WithScope = new IPAddress(
                      			new byte[] { 0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, 0, 0, 0x8a, 0x2e, 0x03, 0x70, 0x73, 0x34 },
                                  15); // 接口索引
                      

                      3)安全解析 IP 地址

                      if (IPAddress.TryParse("203.0.113.5", out IPAddress? address))
                      {
                          Console.WriteLine($"有效地址: {address}");
                      }
                      else
                      {
                          Console.WriteLine("无效IP地址格式");
                      }
                      

                      注意Parse 方法在格式错误时会抛出 FormatException,推荐优先使用 TryParse

                      2. 特殊IP地址的静态字段

                      IPAddress类提供了几个静态字段,用于表示特殊IP地址:

                      // 0.0.0.0:表示所有接口
                      Console.WriteLine(IPAddress.Any); // 输出:0.0.0.0
                      
                      // 255.255.255.255:表示不使用任何接口(等同于虚四地址)
                      Console.WriteLine(IPAddress.None); // 输出:255.255.255.255
                      
                      // IPv6的特殊地址
                      Console.WriteLine(IPAddress.IPv6Any); // 输出:::
                      
                      // 回环地址
                      Console.WriteLine(IPAddress.Loopback);	//输出 127.0.0.1
                      

                      绑定所有接口:使用IPAddress.Any作为Socket的绑定地址:

                      var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                      socket.Bind(new IPEndPoint(IPAddress.Any, 8080));
                      

                      虚四地址(广播):使用IPAddress.None表示不绑定任何接口:

                      // 通常用于特定协议的广播场景
                      

                      回环地址判断:使用IPAddress.Loopback表示回环地址,使用IPAddress.IsLoopback判断当前IP地址是否是回环地址 :

                      // 回环地址
                      bool isLoopback = IPAddress.IsLoopback(IPAddress.Parse("192.168.1.1"));
                      Console.WriteLine(isLoopback);  //输出 False
                      
                      isLoopback = IPAddress.IsLoopback(IPAddress.Loopback);
                      Console.WriteLine(isLoopback);  //输出 True
                      

                      3. 字节数组与IP地址转换

                      通过构造函数或GetAddressBytes方法实现:

                      // 从字节数组创建IPv4地址
                      IPAddress iPAddress = new IPAddress(new byte[] { 192, 168, 1, 1 });
                      
                      // 获取IP地址的字节数组
                      byte[] bytes= iPAddress.GetAddressBytes();
                      Console.WriteLine(string.Join(".",bytes)); // 输出:192.168.1.1
                      

                      4. IP地址与字符串转换

                      // IPv4 解析  
                      IPAddress ipv4 = IPAddress.Parse("192.168.1.1");
                      // IPv6 解析  
                      IPAddress ipv6 = IPAddress.Parse("2001:db8::8a2e:370:7334");
                      
                      Console.WriteLine(ipv4.ToString()); // 输出:192.168.1.1
                      Console.WriteLine(ipv6.ToString()); // 输出:2001:db8::8a2e:370:7334
                      
                      // 无压缩格式(使用 Replace 去掉压缩格式)  
                      // string fullFormat = ipv6.ToString().Replace("::", ":0:");  
                      Console.WriteLine(ipv6.ToString().Replace("::", ":0:")); // 输出:2001:db8:0:8a2e:370:7334
                      

                      IPv6 转字符串

                      // 标准格式化  
                      string ipv6String = ipv6.ToString(); 
                      
                      // 无压缩格式  
                      string fullFormat = ipv6.ToString().Replace("::", ":0:");  
                      

                      5. IP地址与整数转换

                      在C#中,IP地址(尤其是IPv4)可以与整数进行相互转换。这种转换在某些场景下非常有用,比如将IP地址存储到数据库中以节省空间、进行快速比较或排序等。

                      1)IPv4 地址与整数的转换原理

                      IPv4地址本质上是一个32位的无符号整数,通常以点分十进制形式表示(如192.168.1.10)。每个部分(称为八位组或字节)占用一个字节(8位),范围是0-255

                      例如:

                      192.168.1.10
                      

                      对应的二进制表示为:

                      11000000 10101000 00000001 00001010
                      

                      将其视为一个32位整数时:

                      11000000101010000000000100001010 (十六进制:C0A8010A)
                      

                      对应的十进制值为:

                      3232235786
                      

                      2)从 IP 地址转换为整数

                      ▶ 方法 1:使用IPAddress.GetAddressBytes

                      通过获取IP地址的字节数组,逐字节计算其整数值:

                      using System;
                      using System.Net;
                      
                      class Program
                      {
                          static void Main()
                          {
                              // 示例IP地址
                              string ipAddress = "192.168.1.10";
                              IPAddress ip = IPAddress.Parse(ipAddress);
                      
                              // 转换为整数
                              byte[] bytes = ip.GetAddressBytes();
                              uint ipAsInt = (uint)((bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] << 8) | bytes[3]);
                      
                              Console.WriteLine($"IP地址 {ipAddress} 转换为整数: {ipAsInt}");
                              // 输出:IP地址 192.168.1.10 转换为整数: 3232235786
                          }
                      }
                      

                      ▶ 方法 2:使用BitConverter和位运算

                      BitConverter可以直接将字节数组转换为整数,但需要注意字节顺序(大端 vs 小端):

                      using System;
                      using System.Net;
                      
                      class Program
                      {
                          static void Main()
                          {
                              // 示例IP地址
                              string ipAddress = "192.168.1.10";
                              IPAddress ip = IPAddress.Parse(ipAddress);
                      
                              // 获取字节数组并反转(确保大端顺序)
                              byte[] bytes = ip.GetAddressBytes();
                              if (BitConverter.IsLittleEndian)
                                  Array.Reverse(bytes);
                      
                              // 转换为整数
                              uint ipAsInt = BitConverter.ToUInt32(bytes, 0);
                              Console.WriteLine($"IP地址 {ipAddress} 转换为整数: {ipAsInt}");
                              // 输出:IP地址 192.168.1.10 转换为整数: 3232235786
                          }
                      }
                      

                      3)从整数转换为 IP 地址

                      ▶ 方法 1:使用位运算拆分字节

                      将整数按位拆分为四个字节,并重新组合为IP地址:

                      using System;
                      using System.Net;
                      
                      class Program
                      {
                          static void Main()
                          {
                              // 示例整数
                              uint ipAsInt = 32编程客栈32235786;
                      
                              // 拆分字节
                              byte[] bytes = new byte[4];
                              bytes[0] = (byte)((ipAsInt >> 24) & 0xFF); // 高字节
                              bytes[1] = (byte)((ipAsInt >> 16) & 0xFF);
                              bytes[2] = (byte)((ipAsInt >> 8) & 0xFF);
                              bytes[3] = (byte)(ipAsInt & 0xFF);         // 低字节
                      
                              // 组编程合为IP地址
                              IPAddress ip = new IPAddress(bytes);
                              Console.WriteLine($"整数 {ipAsInt} 转换为IP地址: {ip}");
                              // 输出:整数 3232235786 转换为IP地址: 192.168.1.10
                          }
                      }
                      

                      ▶ 方法 2:使用BitConverter

                      通过BitConverter将整数转换为字节数组,并注意字节顺序:

                      using System;
                      using System.Net;
                      
                      class Program
                      {
                          static void Main()
                          {
                              // 示例整数
                              uint ipAsInt = 3232235786;
                      
                              // 转换为字节数组
                              byte[] bytes = BitConverter.GetBytes(ipAsInt);
                              if (BitConverter.IsLittleEndian)
                                  Array.Reverse(bytes);
                      
                              // 组合为IP地址
                              IPAddress ip = new IPAddress(bytes);
                              Console.WriteLine($"整数 {ipAsInt} 转换为IP地址: {ip}");
                              // 输出:整数 3232235786 转换为IP地址: 192.168.1.10
                          }
                      }
                      

                      4)转换须知

                      • IPv6 不支持直接转换: IPv6地址是128位的,无法直接用uint表示。如果需要处理IPv6,建议使用字符串存储或第三方库(如BigInteger)。

                      • 字节顺序: C#默认是小端模式(低位在前),而IP地址通常是以大端模式存储的。因此,在转换时可能需要手动调整字节顺序。

                      • IPv4地址转换为整数的适用场景

                        • 数据库存储优化:将IP地址存储为整数,减少存储空间。
                        • 快速比较:整数比较比字符串比较更高效。
                        • 排序:整数排序天然支持升序/降序排列。

                      6. 获取 IP 地址的二进制形式

                      通过 GetAddressBytes 方法可以获取 IP 地址的字节数组表示。

                      IPAddress ipv4 = IPAddress.Parse("192.168.1.1");
                      byte[] bytes = ipv4.GetAddressBytes();
                      Console.WriteLine(BitConverter.ToString(bytes)); // 输出:C0-A8-01-01
                      

                      7. 判断 IP 地址类型

                      可以使用 AddressFamily 属性来判断 IP 地址是 IPv4 还是 IPv6。

                      // IPv4 解析  
                      IPAddress ipv4 = IPAddress.Parse("192.168.1.1");
                      Console.WriteLine(ipv4.AddressFamily); // 输出:InterNetwork
                      
                      // IPv6 解析  
                      IPAddress ipv6 = IPAddress.Parse("2001:db8::8a2e:370:7334");
                      Console.WriteLine(ipv6.AddressFamily); // 输出:InterNetworkV6
                      
                      IPAddress ip = IPAddress.Parse("192.168.1.10");
                      Console.WriteLine($"是否为IPv4: {ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork}");
                      

                      三、高级用法

                      1. 与Dns类 配合使用

                      1)获取本地IP地址

                      通过Dns.GetHostEntryIPAddress的静态方法获取本机IP地址:

                      // 获取本机所有IP地址
                      var host = Dns.GetHostEntry(Dns.GetHostName());
                      foreach (var ip in host.AddressList)
                      {
                          Console.WriteLine($"本机IP地址: {ip}");
                      }
                      
                      // 直接获取IPv4地址(排除IPv6)
                      var ipv4Addresses = host.AddressList
                          .Where(ip => ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                          .ToList();
                      

                      2)解析域名到IP地址

                      使用Dns.GetHostAddresses

                      var googleIps = Dns.GetHostAddresses("google.com");
                      foreach (var ip in googleIps)
                      {
                          Console.WriteLine($"Google IP地址: {ip}");
                      }
                      

                      2. 私有地址检测

                      1)代码示例

                      public static bool IsPrivateAddress(IPAddress ip)  
                      {  
                          if (ip.AddressFamily == AddressFamily.InterNetwork)  
                          {  
                              byte[] bytes = ip.GetAddressBytes();  
                              return bytes[0] == 10 ||  
                                  (bytes[0] == 172 && bytes[1] >= 16 && bytes[1] <= 31) ||  
                                  (bytes[0] == 192 && bytes[1] == 168);  
                          }  
                          // IPv6 私有地址检测(ULA:fc00::/7)  
                          else if (ip.AddressFamily == AddressFamily.InterNetworkV6)  
                          {  
                              byte[] bytes = ip.GetAddressBytes();  
                              returnwww.devze.com bytes[0] >= 0xFC && bytes[0] <= 0xFD;  
                          }  
                          return false;  
                      }  
                      
                      IPAddress ipv4 = IPAddress.Parse("192.168.1.10");
                      IPAddress ipv6 = IPAddress.Parse("fc00::1");
                      
                      Console.WriteLine(IsPrivateAddress(ipv4)); // 输出:True
                      Console.WriteLine(IsPrivateAddress(ipv6)); // 输出:True
                      
                      IPAddress publicIp = IPAddress.Parse("8.8.8.8");
                      Console.WriteLine(IsPrivateAddress(publicIp)); // 输出:False
                      

                      2)代码分析

                      这段代码实现了一个方法 IsPrivateAddress,用于判断给定的 IP 地址是否属于私有地址范围。私有地址是指在局域网(LAN)中使用的地址,不会直接暴露在公共互联网上。以下是对代码的详细解析:

                      ▶ IPv4 私有地址检测

                      return bytes[0] == 10 ||
                             (bytes[0] == 172 && bytes[1] >= 16 && bytes[1] <= 31) ||
                             (bytes[0] == 192 && bytes[1] == 168);
                      
                      • 根据 RFC 1918,IPv4 私有地址范围包括以下三段:
                        1. 10.0.0.0/8:从 10.0.0.0 到 10.255.255.255
                          • 判断条件:bytes[0] == 10
                        2. 172.16.0.0/12:从 172.16.0.0 到 172.31.255.255
                          • 判断条件:bytes[0] == 172 && bytes[1] >= 16 && bytes[1] <= 31
                        3. 192.168.0.0/16:从 192.168.0.0 到 192.168.255.255
                          • 判断条件:bytes[0] == 192 && bytes[1] == 168
                      • 如果满足上述任意一个条件,则返回 true,表示该 IP 地址是私有地址。

                      ▶ IPv6 私有地址检测

                      return bytes[0] >= 0xFC && bytes[0] <= 0xFD;
                      
                      • 根据 RFC 4193,IPv6 私有地址(称为唯一本地地址,ULA)的范围是 fc00::/7
                        • 前 7 位固定为 1111110,对应十六进制为 FC 或 FD。
                        • 判断条件:bytes[0] >= 0xFC && bytes[0] <= 0xFD
                      • 如果满足条件,则返回 true,表示该 IPv6 地址是私有地址。

                      ▶ 使用场景

                      • 网络编程中,判断某个 IP 地址是否属于局域网范围。
                      • 防火墙规则或网络策略配置中,过滤私有地址流量。

                      3. 检查 IP 地址是否在子网内

                      1)代码示例

                      可以通过计算子网掩码和网络地址来判断 IP 地址是否在某个子网内。

                      public static bool IsInSubnet(IPAddress address, IPAddress subnet, int cidr)
                      {
                          // 参数校验
                          if (address.AddressFamily != subnet.AddressFamily)
                              throw new ArgumentException("IP 地址和子网地址必须为同一协议版本");
                          
                          if (cidr < 0 || 
                              (address.AddressFamily == AddressFamily.InterNetwork && cidr > 32) || 
                              (address.AddressFamily == AddressFamily.InterNetworkV6 && cidr > 128))
                              throw new ArgumentOutOfRangeException(nameof(cidr), "CIDR 范围无效");
                      
                          byte[] ipBytes = address.GetAddressBytes();
                          byte[] subnetBytes = subnet.GetAddressBytes();
                          byte[] maskBytes = new byte[ipBytes.Length];
                      
                          // 生成掩码
                          int remainingCidr = cidr;
                          for (int i = 0; i < maskBytes.Length && remainingCidr > 0; i++)
                          {
                              int bitsToSet = Math.Min(8, remainingCidr);
                              maskBytes[i] = (byte)(0xFF << (8 - bitsToSet));
                              remainingCidr -= bitsToSet;
                          }
                      
                          // 比较掩码后的结果
                          for (int i = 0; i < ipBytes.Length; i++)
                          {
                              if ((ipBytes[i] & maskBytes[i]) != (subnetBytes[i] & maskBytes[i]))
                                  return false;
                          }
                      
                          return true;
                      }
                      
                      // 示例
                      IPAddress ipv4 = IPAddress.Parse("192.168.1.10");
                      IPAddress subnetv4 = IPAddress.Parse("192.168.1.0");
                      int cidr = 24;
                      
                      Console.WriteLine(IsInSubnet(ipv4, subnetv4, cidr)); // 输出:True
                      
                      IPAddress ipv6 = IPAddress.Parse("2001:db8::1");
                      IPAddress subnetv6 = IPAddress.Parse("2001:db8::");
                      cidr = 64;
                      
                      Console.WriteLine(IsInSubnet(ipv6, subnetv6, cidr)); // 输出:True
                      

                      2)代码分析

                      该方法 IsInSubnet 用于判断一个 IP 地址(address)是否属于由子网地址(subnet)和 CIDR 掩码(cidr)定义的子网。核心逻辑是通过计算子网掩码,然后比较 IP 地址与子网地址在掩码部分是否一致。

                      ▶ 子网掩码生成

                          // 生成掩码
                          int remainingCidr = cidr;
                          for (int i = 0; i < maskBytes.Length && remainingCidr > 0; i++)
                          {
                              int bitsToSet = Math.Min(8, remainingCidr);
                              maskBytes[i] = (byte)(0xFF << (8 - bitsToSet));
                              remainingCidr -= bitsToSet;
                          }
                      

                      ▶ IP 地址与子网地址的掩码比较

                          // 比较掩码后的结果
                          for (int i = 0; i < ipBytes.Length; i++)
                          {
                              if ((ipBytes[i] & maskBytes[i]) != (subnetBytes[i] & maskBytes[i]))
                                  return false;
                          }
                      	return true;
                      
                      • 逻辑
                        • 对每个字节,将 IP 地址和子网地址与掩码进行按位与操作。
                        • 如果结果不一致,则说明该 IP 不在子网内,返回 false
                        • 否则,所有字节均匹配,返回 true
                      ▶ 适用场景

                      网络编程中判断 IP 地址是否属于特定子网,如防火墙规则、路由配置等。

                      ▶ 重载方法

                      public static bool IsInSubnet(IPAddress address, IPAddress subnet, int cidr)
                      

                      仅展示核心逻辑(缺少参数校验)如下:

                      public static bool IsInSubnet(IPAddress address, IPAddress subnet, IPAddress mask)  
                      {  
                          byte[] addressBytes = address.GetAddressBytes();  
                          byte[] subnetBytes = subnet.GetAddressBytes();  
                          byte[] maskBytes = mask.GetAddressBytes();  
                      
                          for (int i = 0; i < addressBytes.Length; i++)  
                              if ((addressBytes[i] & maskBytes[i]) != subnetBytes[i])  
                                  return false;  
                          return true;  
                      }  
                      

                      4. CIDR 表示法解析

                      1)解析IP 和 掩码

                      public static (IPAddress Address, int Prefix) ParseCidr(string cidr)  
                      {  
                          string[] parts = cidr.Split('/');  
                          IPAddress address = IPAddress.Parse(parts[0]);  
                          int prefix = int.Parse(parts[1]);  
                          return (address, prefix);  
                      }  
                      
                      // 使用示例  
                      var (baseIp, prefix) = ParseCidr("192.168.1.0/24");  
                      

                      仅展示核心逻辑

                      2) CIDR格式转换(掩码转为CIDR表示)

                      // 将掩码转换为CIDR表示
                      public static int GetCidr(IPAddress subnetMask)
                      {
                          byte[] bokLvHytes = subnetMask.GetAddressBytes();
                          int cidr = 0;
                          
                          foreach (byte b in bytes)
                          {
                              if (b == 0xFF)
                              {
                                  cidr += 8;
                                  continue;
                              }
                              
                              byte mask = 0x80;
                              while (mask > 0)
                              {
                                  if ((b & mask) == mask) cidr++;
                                  else break;
                                  mask >>= 1;
                              }
                              break;
                          }
                          return cidr;
                      }
                      

                      仅展示核心逻辑

                      3)子网掩码计算(CIDR掩码转为IP地址格式)

                      // 生成 CIDR 掩码  
                      int cidr = 24;  
                      IPAddress mask = IPAddress.Parse("255.255.255.0");  
                      // 或自动生成  
                      byte[] cidrBytes = new byte[4];  
                      for (int i = 0; i < cidr; i++)  
                          cidrBytes[i / 8] |= (byte)(0x80 >> (i % 8));  
                      IPAddress cidrMask = new IPAddress(cidrBytes);  
                      
                      // 生成CIDR掩码
                      public static IPAddress CreateSubnetMask(int cidr, bool isIPv6 = false)
                      {
                          if (isIPv6) cidr += 96; // 调整IPv6 CIDR范围
                      
                          byte[] bytes = new byte[isIPv6 ? 16 : 4];
                          for (int i = 0; i < bytes.Length; i++)
                          {
                              if (cidr >= 8)
                              {
                                  bytes[i] = 0xFF;
                                  cidr -= 8;
                              }
                              else
                              {
                                  bytes[i] = (byte)(0xFF << (8 - cidr));
                                  break;
                              }
                          }
                          return new IPAddress(bytes);
                      }
                      

                      仅展示核心逻辑

                      5. 网络接口处理

                      // 获取本机所有IP地址
                      foreach (NetworkInterface nic in NetworkInterface.GetAllNetworkInterfaces())
                      {
                          foreach (UnicastIPAddressInformation ip in nic.GetIPProperties().UnicastAddresses)
                          {
                              Console.WriteLine($"{nic.Name}: {ip.Address}");
                          }
                      }
                      

                      6. IPv4与IPv6映射

                      // IPv4转IPv6映射地址
                      IPAddress v4MappedV6 = ipv4.MapToIPv6();
                      
                      // IPv6转IPv4(仅当是映射地址时)
                      if (ipv6.IsIPv4MappedToIPv6)
                      {
                          IPAddress v4 = ipv6.MapToIPv4();
                      }
                      
                      // 强制转换为 IPv4  
                      if (ip.AddressFamily == AddressFamily.Inwww.devze.comterNetworkV6 && ip.IsIPv4MappedToIPv6)  
                      {  
                          IPAddress ipv4 = ip.MapToIPv4();  
                      }  
                      

                      四、性能优化技巧

                      1. 缓存频繁解析的地址

                      private static readonly ConcurrentDictionary<string, IPAddress> addressCache = new();
                      
                      public static IPAddress ParseCached(string ipString)
                      {
                          return addressCache.GetOrAdd(ipString, s => 
                          {
                              if (IPAddress.TryParse(s, out var ip))
                                  return ip;
                              throw new FormatException("无效IP地址格式");
                          });
                      }
                      

                      2. 使用 Span 优化字节操作

                      public static bool IsIPv4MappedToIPv6(IPAddress ip)  
                      {  
                          ReadOnlySpan<byte> bytes = ip.GetAddressBytes().AsSpan();  
                          return ip.IsIPv4MappedToIPv6 &&  
                                 bytes.Slice(0, 12).SequenceEqual(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF });  
                      }  
                      

                      参考资料:

                      • .NET Runtime IPAddress 源码
                      • Microsoft Learn: IPAddress.None
                      • IPAddress.Parse 解析规则
                      • IPAddress 构造函数详解

                      到此这篇关于C# System.Net.IPAddress的使用小结的文章就介绍到这了,更多相关C# System.Net.IPAddress内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)! 

                      0

                      上一篇:

                      下一篇:

                      精彩评论

                      暂无评论...
                      验证码 换一张
                      取 消

                      最新开发

                      开发排行榜