首页 > 编程语言 >C# 获取局域网下的设备IP范围

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

时间:2023-05-20 10:03:47浏览次数:59  
标签:return C# IP 局域网 二进制 var byte IPAddress

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

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

C# 获取局域网下的设备IP范围_二进制数

 那自动分配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的博客-

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

作者:唐宋元明清2188

本文版权归作者有,欢迎转载,但未经作者同意必须在文章页面给出原文连接,否则保留追究法律责任的权利。


标签:return,C#,IP,局域网,二进制,var,byte,IPAddress
From: https://blog.51cto.com/u_13906430/6317173

相关文章

  • Connections could not be acquired from the underlying database!
    报错内容:五月19,20239:02:42上午org.apache.catalina.core.StandardWrapperValveinvoke严重:在路径为的上下文中,Servlet[springmvc]的Servlet.service()引发了具有根本原因的异常Requestprocessingfailed;nestedexceptionisorg.springframework.transaction.CannotCreat......
  • flutter系列之:使用AnimationController来控制动画效果
    目录简介构建一个要动画的widget让图像动起来总结简介之前我们提到了flutter提供了比较简单好用的AnimatedContainer和SlideTransition来进行一些简单的动画效果,但是要完全实现自定义的复杂的动画效果,还是要使用AnimationController。今天我们来尝试使用AnimationController来实现......
  • golang命令行cobra 快速入门教程
    cobra也许是go语言现有最好的命令行框架了,在各大项目中皆有使用,比如最出名的kubernetes,所以要写一个稍微复杂的命令行工具,使用cobra还是不错的,cobra内置了非常多有用的功能,包括但不限于,自动生成帮助文档,生成命令行代码的脚手架工具,智能提示等等。命令行相关知识在学习cobr......
  • c++STL—容器map/multimap
    1、map基本概念1.1、简介map中所有元素都是pairpair中第一个元素为key(键值),起到索引作用,第二个元素为value(实值)所有元素都会根据元素的键值自动排序1.2、本质map/multimap属于关联式容器,底层结构是用二叉树实现。1.3、优点可以根据key值快速找到value值1.4、map和multimap区别map不......
  • 计算机网络--Ch5.传输层(三)
    六.流量控制流量控制:让发送方慢点,要让接收方来得及接收。TCP利用滑动窗口机制实现流量控制。A向B发送数据,连接建立时,B告诉A:“我的rwnd=400(字节)”,设每一个报文段100B,报文段序号初始值为1。TCP为每一个连接设有一个持续计时器,只要TCP连接的一方收到对方的零窗口通知,就启动......
  • TheForces Round #13 (Boombastic-Forces) G. Permutation Removal
    感觉好久没有写过这样单独一篇题目的博客了的说昨天上大物课的时候ztc问了我这道题,然后我口胡了下感觉还挺有趣的不过其它题目就没啥时间看了,正巧最近在练DP专题,就顺手记录一下吧这题的数据范围和问题一眼区间DP的形式,直接设\(f_{l,r}\)表示区间\([l,r]\)的答案刚开始naive地......
  • docker-compose
    Compose允许用户通过一个单独的docker-compose.yml模板文件(YAML格式)来定义一组相关联的应用容器为一个项目(project)一安装:用于一次性部署多个容器,通过一个yml文件来启动 1.curl-L"https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname-s)-......
  • cpp: Singleton Pattern
     //GoldConfig.h:此文件包含"GoldConfig"类。装饰器模式SingletonPatternC++14////SingletonPattern单例模式单件模式、Singleton//2023年5月20日涂聚文GeovinDuVisualStudio2022edit.#pragmaonce#ifndefGOLDCONFIG_H#defineGOLDCONFIG_H#i......
  • office与WPS的区别
    声明本篇主要是为了科普下WPSoffice与MSoffice。博主使用的WPS后续也将使用其讲解。如有不妥,欢迎评论。概要大众使用的办公软件目前大致是MSoffice和WPSoffice。学哪一个我感觉都差不多,毕竟它们两者基础功能都差不多(不考虑金钱的话嘿嘿)。MSoffice全称为MicrosoftOf......
  • 常用的标准LCD驱动芯片,性价比高,稳定性好,多种封装型号选择VK1056
    型号:VK1056BVK1056C品牌:永嘉微电/VINKA封装形式:SOP24SSOP24年份:最新年份VK1056B/C概述:VK1056B/C是56点、内存映象和多功能的LCD驱动,VK1056B的软件配置特性使它适用于多种LCD应用场合,包括LCD模块和显示系统,用于连接主控制器和VK1056B的管脚只有4条,VK1056B......