C# 获取局域网下的设备IP范围

我们连接的WIFI,属性设置里有自动分配IP的选项。

我们通过控制台输入ipconfig,看到当前IP是10.214.18.178

 那自动分配IP范围是多少?路由器对IP是怎么分配的。下面是我整理的code,有需要的可以直接Copy

IP范围获取:

1     private void RefreshButton_OnClick(object sender, RoutedEventArgs e)
2     {
3         var maxSubIp = GetMaxSubIp("10.214.18.1", "255.255.254.0");
4         SubNetIpTextBlock.Text = $"10.214.18.1-{maxSubIp}";
5     }

通过子网掩码及默认网关,获取路由可分配的最大IP:

我们将子网掩码转换为二进制数据,11111111111111111111111000000000,这里的1表示固定IP,0表示可分配的动态IP。

再将默认网关也转换为二进制数据,如00101000001101011010010010100000,将这个分成俩段:
“001010000011010110100100”,即上面子网掩码固定长度的部分,我们定义个名称A,分配的IP固定部分就是这部分A

“10100000”,是上面子网掩码动态长度的部分。IP动态段,最低的值就是这个。

所以我们要算出动态IP段的最高值即可。最高值就是二进制全部是1:“11111111”

然后改将二进制数据,转换为十进制的IP地址,就拿到我们动态IP的最大值了。

复制代码
 1     /// <summary>
 2     /// 获取局域网下最大IP
 3     /// </summary>
 4     /// <param name="defaultGateway">默认网关</param>
 5     /// <param name="subNetMask">子网掩码</param>
 6     private string GetMaxSubIp(string defaultGateway, string subNetMask)
 7     {
 8         var subNetBinary = ConvertIpToBinary(subNetMask);
 9         if (!subNetBinary.EndsWith("0"))
10         {
11             return string.Empty;
12         }
13         var existIndex = subNetBinary.IndexOf("0", StringComparison.Ordinal);
14         var gatewayBinary = ConvertIpToBinary(defaultGateway);
15         var maxIpLeft = gatewayBinary.Substring(0, existIndex);
16 
17         //最大的子网IP
18         var maxSubIpBinary = maxIpLeft.PadRight(32, '1');
19         var maxSubIp = ConvertBinaryToIp(maxSubIpBinary);
20         return maxSubIp;
21     }
复制代码

IP与二进制间的转换:

复制代码
 1     /// <summary>
 2     /// 将二进制数据转为IP
 3     /// </summary>
 4     /// <param name="ipBinaryData">IP二进制数据,如:00001010110101100001001000000001</param>
 5     /// <returns>IP地址,如:10.214.18.1</returns>
 6     private string ConvertBinaryToIp(string ipBinaryData)
 7     {
 8         var item1 = Convert.ToInt32(ipBinaryData.Substring(0, 8), 2);
 9         var item2 = Convert.ToInt32(ipBinaryData.Substring(8, 8), 2);
10         var item3 = Convert.ToInt32(ipBinaryData.Substring(16, 8), 2);
11         var item4 = Convert.ToInt32(ipBinaryData.Substring(24, 8), 2);
12         return $"{item1}.{item2}.{item3}.{item4}";
13     }
14 
15     /// <summary>
16     /// 将IP转为二进制数据
17     /// </summary>
18     /// <param name="ipAddress">IP地址,如:10.214.18.1</param>
19     /// <returns>IP二进制数据,如:00001010110101100001001000000001</returns>
20     private string ConvertIpToBinary(string ipAddress)
21     {
22         var items = ipAddress.Split('.');
23         var stringBuilder = new StringBuilder();
24         foreach (var item in items)
25         {
26             var binary = Convert.ToString(int.Parse(item), 2);
27             var ipPieceBinary = binary.PadLeft(8, '0');
28             stringBuilder.Append(ipPieceBinary);
29         }
30         return stringBuilder.ToString();
31     }
复制代码

在上面案例中,子网掩码255.255.254.0,默认网关10.214.18.1,所以这个网络的IP范围是:10.214.18.1-10.214.19.255

上面获取IP范围的原理,就是根据IP地址与掩码进行对比。搞清楚原理后,我优化了下获取IP范围的逻辑

下面直接根据IP地址和子网掩码进行计算,得到IP范围。

获取最小IP:

复制代码
 1     private static IPAddress GetLowestIp(IPAddress address, IPAddress mask)
 2     {
 3         byte[] addressBytes = address.GetAddressBytes();
 4         byte[] maskBytes = mask.GetAddressBytes();
 5         if (addressBytes.Length != 4 || maskBytes.Length != 4)
 6             return IPAddress.None;
 7         byte[] lowest = new byte[4];
 8         for (var i = 0; i < 4; i++)
 9             lowest[i] = (byte)(addressBytes[i] & maskBytes[i]);
10         return new IPAddress(lowest);
11     }
复制代码

获取最大IP:

复制代码
 1     private static IPAddress GetHighestIp(IPAddress address, IPAddress mask)
 2     {
 3         byte[] addressBytes = address.GetAddressBytes();
 4         byte[] maskBytes = mask.GetAddressBytes();
 5         if (addressBytes.Length != 4 || maskBytes.Length != 4)
 6             return IPAddress.None;
 7         byte[] highest = new byte[4];
 8         for (var i = 0; i < 4; i++)
 9             highest[i] = (byte)((addressBytes[i] & maskBytes[i]) | ~maskBytes[i]);
10         return new IPAddress(highest);
11     }
复制代码

 

参考:

(25条消息) npm 获取某个网段下所有的子网_子网掩码与IP地址之间有什么关系?_weixin_39833429的博客-CSDN博客

C# 进制之间转换(二进制、十进制、十六进制) - 知乎 (zhihu.com)

posted @   唐宋元明清2188  阅读(351)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
· 上周热点回顾(2.17-2.23)
点击右上角即可分享
微信分享提示
剑桥
16:15发布
剑桥
16:15发布
7°
西南风
3级
空气质量
相对湿度
66%
今天
2°/10°
周三
2°/8°
周四
中雨
2°/7°