首页 > 编程语言 >C#查询本机所在网段的所有IP以及计算目标IP对应同局域网的本机IP

C#查询本机所在网段的所有IP以及计算目标IP对应同局域网的本机IP

时间:2023-07-15 16:34:35浏览次数:44  
标签:网段 IPAddress ipProps IP var return 本机 addressInfo

1 借助System.Net.NetworkInformation.NetworkInterface 作为切入点获取所有的网卡接口

2 通过NetworkInterface.OperationalStatus 状态判断是否可以传送包

3 通过NetworkInterface.NetworkInterfaceType 判断网卡类型

4 通过UnicastIPAddressInformation.Address 和 UnicastIPAddressInformation.IPv4Mask 计算局域网的所有IP

具体代码如下:

using System.Collections.Generic;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;

namespace Utils
{
    /// <summary>
    /// 子网IP范围查询
    /// </summary>
    public static class SubNetIps
    {
        /// <summary>
        /// 获取所有IP网段
        /// </summary>
        /// <returns></returns>
        public static List<IpRange> GetIpRanges()
        {
            var ranges = new List<IpRange>();
            foreach (NetworkInterface netInterface in NetworkInterface.GetAllNetworkInterfaces())
            {
                var ipProps = GetIpInterfaceProperties(netInterface);
                if (ipProps == null) continue;
                foreach (var addressInfo in ipProps.UnicastAddresses)
                {
                    //忽略非IP4的地址
                    if (addressInfo.Address.AddressFamily != AddressFamily.InterNetwork) continue;
                    var lowestAddress = GetLowestIp(addressInfo.Address, addressInfo.IPv4Mask);
                    var highestAddress = GetHighestIp(addressInfo.Address, addressInfo.IPv4Mask);
                    ranges.Add(new IpRange(lowestAddress, highestAddress));
                }
            }
            return ranges;
        }

        /// <summary>
        /// 获取匹配远方的本地
        /// </summary>
        /// <returns></returns>
        public static IPAddress GetLocalIpByRemoteAddress(IPAddress remoteAddress)
        {
            foreach (NetworkInterface netInterface in NetworkInterface.GetAllNetworkInterfaces())
            {
                var ipProps = GetIpInterfaceProperties(netInterface);
                if (ipProps == null) continue;
                foreach (var addressInfo in ipProps.UnicastAddresses)
                {
                    //忽略非IP4的地址
                    if (addressInfo.Address.AddressFamily != AddressFamily.InterNetwork) continue;
                    var lowestAddress = GetLowestIp(addressInfo.Address, addressInfo.IPv4Mask);
                    var highestAddress = GetHighestIp(addressInfo.Address, addressInfo.IPv4Mask);
                    if (IsBetween(remoteAddress, lowestAddress, highestAddress)) return addressInfo.Address;
                }
            }
            return default(IPAddress);
        }

        /// <summary>
        /// 获取局域网以及能够上网的网卡信息
        /// </summary>
        /// <param name="netInterface"></param>
        /// <returns></returns>
        private static IPInterfaceProperties GetIpInterfaceProperties(NetworkInterface netInterface)
        {
            IPInterfaceProperties ipProps = null;
            if (netInterface.OperationalStatus != OperationalStatus.Up) return null;

            ipProps = netInterface.GetIPProperties();
            if (netInterface.NetworkInterfaceType != NetworkInterfaceType.Wireless80211)
            {
                //忽略默认网关地址为空的适配器
                var dhcpServerAddresses = ipProps.DhcpServerAddresses;
                if (dhcpServerAddresses.Count == 0)
                    ipProps = null;
            }
            return ipProps;
        }

        private static bool IsBetween(IPAddress ipAddress, IPAddress startIP, IPAddress endIP)
        {
            var startBytes = startIP.GetAddressBytes();
            var endBytes = endIP.GetAddressBytes();
            var targetBytes = ipAddress.GetAddressBytes();
            if (startBytes.Length != targetBytes.Length || endBytes.Length != targetBytes.Length) return false;
            bool isBetween = true;
            for (int i = 0; i < startBytes.Length; i++)
            {
                if (startBytes[i] > targetBytes[i] || endBytes[i] < targetBytes[i])
                {
                    isBetween = false;
                    break;
                }
            }
            return isBetween;
        }

        private static IPAddress GetLowestIp(IPAddress address, IPAddress mask)
        {
            byte[] addressBytes = address.GetAddressBytes();
            byte[] maskBytes = mask.GetAddressBytes();
            if (addressBytes.Length != 4 || maskBytes.Length != 4)
                return IPAddress.None;
            byte[] lowest = new byte[4];
            for (var i = 0; i < 4; i++)
                lowest[i] = (byte)(addressBytes[i] & maskBytes[i]);
            return new IPAddress(lowest);
        }
        private static IPAddress GetHighestIp(IPAddress address, IPAddress mask)
        {
            byte[] addressBytes = address.GetAddressBytes();
            byte[] maskBytes = mask.GetAddressBytes();
            if (addressBytes.Length != 4 || maskBytes.Length != 4)
                return IPAddress.None;
            byte[] highest = new byte[4];
            for (var i = 0; i < 4; i++)
                highest[i] = (byte)((addressBytes[i] & maskBytes[i]) | ~maskBytes[i]);
            return new IPAddress(highest);
        }
    }

    public class IpRange
    {
        /// <summary>
        /// 最小动态IP
        /// </summary>
        public IPAddress LowestAddress { get; }
        /// <summary>
        /// 最大可分配动态IP
        /// </summary>
        public IPAddress HighestAddress { get; }

        public IpRange(IPAddress lowestAddress, IPAddress highestAddress)
        {
            LowestAddress = lowestAddress;
            HighestAddress = highestAddress;
        }
    }
}

 

标签:网段,IPAddress,ipProps,IP,var,return,本机,addressInfo
From: https://www.cnblogs.com/terryK/p/17556438.html

相关文章

  • python 多网卡获取ip mac
    Python多网卡获取IP和MAC地址简介在网络编程中,有时候我们需要获取计算机上的多个网卡的IP和MAC地址。Python提供了一些库和方法来实现这个功能。本文将介绍如何通过Python来获取多个网卡的IP和MAC地址,并给出相应的代码示例。流程概述下面是实现该功能的大致流程:步骤动作......
  • 什么是持续集成和持续交付领域的 pipeline 概念
    在软件开发中,Pipeline是一种自动化的过程,它包括从开发人员提交代码,到代码构建,测试,部署等一系列的步骤。在持续集成(ContinuousIntegration)/持续部署(ContinuousDeployment)领域,Pipeline是非常重要的,因为它可以帮助开发团队更快,更有效地构建,测试和部署软件。首先,让我们详细了解下......
  • Ubuntu找不到ip无法ssh登录,解决方法开机自动重启dhcp
    问题VMware里安装的Ubuntu虚拟机,每次开机ifconfig都找不到网卡ens33,就没有ip地址,无法通过xshell进行ssh登录。每次都手动执行sudodhclienens33才可以,下面通过脚本让其开机自启。配置脚本sudovim/etc/rc.local文件里写入下面内容:#!/bin/bashdhclientens33添加执行权限......
  • 10.JavaScript原型,原型链有什么特点
    10.JavaScript原型,原型链?有什么特点?在js中我们是使用构造函数来新建一个对象的,每一个构造函数的内部都有一个prototype属性值,这个属性值是一个对象,这个对象包含了可以由该构造函数的所有实例共享的属性和方法。当我们使用构造函数新建一个对象后,在这个对象的内部将包含......
  • Jenkins pipeline(之Groovy语法简介)
    1.Jenkinspipeline编写风格:Jenkinsfile  声明式风格、脚本式风格  声明式:格式有强规范性(优势:可读性强。缺点:不灵活、代码冗长)  脚本式:使用groovy语言编写,灵活性高,可读性差。优点:实现自定义逻辑更方便、可对功能代码段封装为方法(函数)或类   2.流水线脚本结构n......
  • LeetCode 519. Random Flip Matrix 哈希Map
    Thereisanmxnbinarygridmatrixwithallthevaluesset0initially.Designanalgorithmtorandomlypickanindex(i,j)wherematrix[i][j]==0andflipsitto1.Alltheindices(i,j)wherematrix[i][j]==0shouldbeequallylikelytobereturne......
  • TIPS清洁和缩小毛孔
    清洁和缩小毛孔是许多人关注的美容问题。以下是一些常见的方法来清洁和缩小毛孔:清洁步骤:每天使用温和的洗面奶清洁脸部,特别注意T区(额头、鼻子和下巴)的清洁。避免使用过度刺激或含有硫酸盐的产品,因为它们可能使皮肤更干燥。定期去角质,以帮助去除死皮细胞和深层清洁毛孔。选择......
  • docker 检查SQL Server实例的TCP/IP协议是否已启用
    检查SQLServer实例的TCP/IP协议是否已启用作为一名经验丰富的开发者,我将帮助你学习如何检查SQLServer实例的TCP/IP协议是否已启用。以下是整个流程以及每一步需要做的事情。流程步骤描述1连接到SQLServer实例2查询是否已启用TCP/IP协议3根据查询结果判断TC......
  • JavaScript at() 方法
    数组对象:对于获取数组的最后一个元素,可能平常见得多的就是arr[arr.length-1],我们其实可以使用at()方法进行获取接收一个整数值并返回该索引对应的元素:constarr=[5,12,8,130,44];letindex1=2;strt1=`索引号为${index1}的值为${arr.at(index1)}`;letind......
  • 【javascript】关于文件下载
    通常在a标签href属性后加上请求下载文件的地址,页面点击即可下载,该种方式是交由浏览器去下载,但是无法监听下载进度若通过AJAX请求,则需要对其进行解析,通常将数据转为blob,然后模拟a标签点击事件,但是此方法如果文件过大,接口调用时超出ajax的timeout时长,会下载失败......