简体   繁体   English

从本地网络 C# 获取所有 IP 时出现问题

[英]Problem while getting all IP's from local network C#

I have tried a lot of solutions on internet for getting IP's from my local network and all of them have been failed to get all IP's.我在互联网上尝试了很多从本地网络获取 IP 的解决方案,但所有这些解决方案都未能获取所有 IP。 I also try to get IP's using ARP commands "arp /a" and "arp -a" but this command is also unable to do the job finally after searching for a while I found a software called "Advance IP Scanner" and when I run this software it gets all the IP's from local network and the most strange thing for me is that after running the Advance IP Scanner when I run the ARP command "arp /a" or "arp -a" it gets all the IP's from my local network.我也尝试使用 ARP 命令“arp /a”和“arp -a”来获取 IP,但是在搜索了一段时间后,这个命令也无法完成这项工作,我找到了一个名为“Advance IP Scanner”的软件,当我运行该软件从本地网络获取所有 IP,对我来说最奇怪的是,在运行 Advance IP 扫描仪后,当我运行 ARP 命令“arp /a”或“arp -a”时,它会从我的本地获取所有 IP网络。

This is what I have tried.这是我尝试过的。

 public List<IPScanEntity> GetArpResult()
        {
            List<IPScanEntity> List = new List<IPScanEntity>();
            
            string baseIp = ConfigurationManager.AppSettings["baseIp"];

            //getting my own system IP
            List.Add(HostIPScanResult());
            for (int subnet = 1; subnet < 255; subnet++)
            {
                bool a = List.Any(x => x.Ip.Equals(baseIp+subnet.ToString()));

                if (a == true)
                {
                    continue;
                }

                try
                {
                    var p = Process.Start(new ProcessStartInfo("arp", "/a " + baseIp + subnet)
                    {
                        CreateNoWindow = true,
                        UseShellExecute = false,
                        RedirectStandardOutput = true
                    });

                    var output = p?.StandardOutput.ReadToEnd();
                    p?.Close();
                    var lines = output.Split('\n').Where(l => !string.IsNullOrWhiteSpace(l));
                    if (!lines.Contains("No ARP Entries Found.\r"))
                    {
                        var result =
                        (from line in lines
                         select Regex.Split(line, @"\s+")
                            .Where(i => !string.IsNullOrWhiteSpace(i)).ToList()
                            into items
                         where items.Count == 3                        
                         select new IPScanEntity
                         {
                             Ip = items[0],
                             MacAddress = items[1],
                         });
                        List.Add(result.FirstOrDefault());
                    }
                }
                catch (Exception ex)
                {
                    log.Error(ex.Message);                    
                }                
            }
         
            return List;
        }

The Problem with arp is it only lists IP-Addresses your system is aware of (it already communicated with). arp 的问题在于它只列出了您的系统知道的 IP 地址(它已经与之通信)。

If you really want to get all IPs you should loop a ping for your subnet.如果您真的想获得所有 IP,您应该为您的子网循环 ping。 (see the link posted by Mikael for example) (例如,请参阅Mikael 发布的链接

Edit 1)编辑 1)

If the ICM Protocol is blocked by the machine (is enabled by default) and you know a port that is open you can use a tool like PPing to ping a specific tcp/udp port.如果 ICM 协议被机器阻止(默认启用)并且您知道一个打开的端口,您可以使用PPing 之类的工具来 ping 特定的 tcp/udp 端口。 Maybe theres some other tool I don't know about with an api or exitcode support, if not you can use this wrapper I wrote for pping:也许还有一些我不知道的其他工具与 api 或退出代码支持,如果不是你可以使用我为 ping 编写的这个包装器:

public static bool PPing(string host, int port, PPingProtocolType type = PPingProtocolType.tcp)
{
  var cmdOutput = new StringBuilder();
  var cmdStartInfo = new ProcessStartInfo()
  {
    //Path to PPing.exe
    FileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tools", "pping.exe"),
    Arguments = $"-r 1 -w 0{(type == PPingProtocolType.udp ? " -u " : " ")}{host} {port}",
    UseShellExecute = false,
    RedirectStandardOutput = true,
    CreateNoWindow = true,
  };

  using (Process proc = Process.Start(cmdStartInfo))
  {
    while (!proc.StandardOutput.EndOfStream)
    {
      cmdOutput.AppendLine(proc.StandardOutput.ReadLine());
    }
  }

  return cmdOutput.ToString().Contains("(1 OPEN, 0 CLOSED)");
}

public enum PPingProtocolType
{
  tcp = 0,
  udp = 1,
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM