C#怎么获取局域网所有IP

来源:IPIPP.com作者:广州GEO公司头衔:草根站长
导读:本期聚焦于小伙伴创作的《C#怎么获取局域网所有IP》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《C#怎么获取局域网所有IP》有用,将其分享出去将是对创作者最好的鼓励。

获取局域网所有IP是很多内网工具开发的基础需求,结合ARP广播和Ping并发的方式可以在保证扫描速度的同时提高结果准确性。ARP广播可以直接从系统ARP缓存中获取已通信设备的IP信息,Ping并发则可以批量检测未出现在ARP缓存中的存活IP,两者互补能覆盖更多场景。

一、ARP广播获取局域网IP

ARP协议的作用是将IP地址解析为对应的MAC地址,系统会维护一个ARP缓存表,记录近期通信过的设备的IP和MAC对应关系。我们可以通过读取系统的ARP缓存表,快速获取同网段内已经有过通信的设备的IP信息,这种方式不需要发送探测包,速度非常快。

1. ARP缓存读取实现

在C#中可以通过调用系统命令arp -a获取ARP缓存内容,然后解析输出结果提取IP地址。以下是具体实现代码:

using System;
using System.Diagnostics;
using System.Text.RegularExpressions;
using System.Collections.Generic;

public class ArpScanner
{
    /// <summary>
    /// 获取ARP缓存中的所有IP地址
    /// </summary>
    /// <returns>IP地址列表</returns>
    public static List<string> GetArpIps()
    {
        List<string> ipList = new List<string>();
        try
        {
            Process process = new Process();
            process.StartInfo.FileName = "arp";
            process.StartInfo.Arguments = "-a";
            process.StartInfo.UseShellExecute = false;
            process.StartInfo.RedirectStandardOutput = true;
            process.StartInfo.CreateNoWindow = true;
            process.Start();
            string output = process.StandardOutput.ReadToEnd();
            process.WaitForExit();

            // 匹配IP地址的正则表达式
            Regex ipRegex = new Regex(@"(d{1,3}.){3}d{1,3}");
            MatchCollection matches = ipRegex.Matches(output);
            foreach (Match match in matches)
            {
                string ip = match.Value;
                // 过滤无效IP和回环地址
                if (IsValidIp(ip) && !ip.StartsWith("127.") && !ipList.Contains(ip))
                {
                    ipList.Add(ip);
                }
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("读取ARP缓存失败:" + ex.Message);
        }
        return ipList;
    }

    /// <summary>
    /// 验证IP地址是否合法
    /// </summary>
    private static bool IsValidIp(string ip)
    {
        string[] parts = ip.Split('.');
        if (parts.Length != 4) return false;
        foreach (string part in parts)
        {
            if (!int.TryParse(part, out int num) || num < 0 || num > 255)
            {
                return false;
            }
        }
        return true;
    }
}

2. 使用说明

调用GetArpIps方法即可直接获取当前系统ARP缓存中的所有合法IP地址,但是这种方式只能获取已经和本机有过通信的设备IP,新接入局域网且未通信的设备无法被检测到。

二、Ping并发扫描局域网IP

为了获取更多未出现在ARP缓存中的存活IP,我们可以使用Ping的方式批量检测同网段的所有IP地址。使用并发Ping可以大幅提升扫描速度,避免逐个Ping等待超时导致的耗时过长问题。

1. 并发Ping实现

以下是使用Task实现并发Ping扫描的代码,支持自定义扫描的IP段和并发数量:

using System;
using System.Net.NetworkInformation;
using System.Collections.Generic;
using System.Threading.Tasks;

public class PingScanner
{
    /// <summary>
    /// 并发Ping扫描指定网段的所有IP
    /// </summary>
    /// <param name="baseIp">网段基础IP,例如192.168.1</param>
    /// <param name="start">起始主机位</param>
    /// <param name="end">结束主机位</param>
    /// <param name="timeout">Ping超时时间(毫秒)</param>
    /// <returns>存活的IP地址列表</returns>
    public static async Task<List<string>> ScanIpsAsync(string baseIp, int start, int end, int timeout = 1000)
    {
        List<string> aliveIps = new List<string>();
        List<Task> tasks = new List<Task>();
        for (int i = start; i <= end; i++)
        {
            string ip = $"{baseIp}.{i}";
            tasks.Add(Task.Run(async () =>
            {
                try
                {
                    Ping ping = new Ping();
                    PingReply reply = await ping.SendPingAsync(ip, timeout);
                    if (reply.Status == IPStatus.Success)
                    {
                        lock (aliveIps)
                        {
                            aliveIps.Add(ip);
                        }
                    }
                }
                catch
                {
                    // 忽略Ping失败的异常
                }
            }));
        }
        await Task.WhenAll(tasks);
        return aliveIps;
    }
}

2. 使用说明

调用ScanIpsAsync方法时,传入网段基础IP、起始主机位、结束主机位和超时时间即可,方法会返回所有Ping通的IP地址。例如扫描192.168.1.1到192.168.1.254的网段,可以调用await PingScanner.ScanIpsAsync("192.168.1", 1, 254);

三、两种方式结合实现完整扫描

将ARP缓存获取和Ping并发扫描结合,既可以利用ARP的快速特性,又能覆盖未通信的存活设备,实现更完整的局域网IP扫描。以下是组合使用的示例代码:

using System;
using System.Collections.Generic;
using System.Threading.Tasks;

class Program
{
    static async Task Main(string[] args)
    {
        Console.WriteLine("开始扫描局域网IP...");
        
        // 第一步:获取ARP缓存中的IP
        List<string> arpIps = ArpScanner.GetArpIps();
        Console.WriteLine($"ARP缓存中获取到{arpIps.Count}个IP:");
        foreach (string ip in arpIps)
        {
            Console.WriteLine(ip);
        }

        // 第二步:并发Ping扫描整个C段,这里假设本机网段是192.168.1
        Console.WriteLine("开始Ping扫描整个网段...");
        List<string> pingIps = await PingScanner.ScanIpsAsync("192.168.1", 1, 254);
        Console.WriteLine($"Ping扫描获取到{pingIps.Count}个存活IP:");
        foreach (string ip in pingIps)
        {
            Console.WriteLine(ip);
        }

        // 合并去重结果
        HashSet<string> allIps = new HashSet<string>(arpIps);
        foreach (string ip in pingIps)
        {
            allIps.Add(ip);
        }
        Console.WriteLine($"最终扫描到{allIps.Count}个局域网IP:");
        foreach (string ip in allIps)
        {
            Console.WriteLine(ip);
        }
    }
}

四、注意事项

  • ARP缓存获取方式依赖系统ARP表,不同系统的ARP缓存过期时间不同,可能无法获取所有设备
  • 并发Ping扫描不要设置过高的并发数,避免被系统判定为异常流量,建议并发数控制在50以内
  • 扫描前需要确认本机所在的网段,避免扫描非本网的IP段导致无效请求
  • 部分设备可能禁用了ICMP响应,会导致Ping扫描无法检测到这些设备

C#ARP广播Ping扫描局域网IP扫描修改时间:2026-06-22 09:46:09

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。