zoukankan      html  css  js  c++  java
  • 用C#获取局域网内所有机器

    如果你使用过P2P终结者或者类似的软件,你会发觉只要一打开就可以看到局域网内部的所有机器,而有时候我们正好有这样的需求,那我们应该怎么样用去获得局域网的所有机器呢?如果你到百度或者GOOGLE上面进行搜索你会发现,网上大致都是采用轮询的方法,让你把所有机器都扫描一遍,如果有反应则表示主机存在,但是这种办法并不可取,不仅耗资源,而且耗时间,即使你单独开一个线程去跑,估计半小时都没有任何结果。网上有人提出更加可笑的办法,说开多一些线程去检测。要知道,线程可不是省油的灯,再说,采用轮询的办法每遇到一台主机不存在就会抛出一个异常,而且该类异常一般都是超时无响应才抛出的,使用异常处理的方式来处理问题将会严重影响应用程序的性能。

    这里将介绍如何利用巧妙的方式来获取局域网内所有机器:


           // 1.先调用系统API判断网络是否处于连接状态
        [DllImport("wininet.dll")]
        private static extern bool InternetGetConnectedState(out int connectionDescription, int reservedValue);

        public static bool IsLocalConnection()
        {
            int connectionDescription = 0;
            return InternetGetConnectedState(out connectionDescription, 0);
        }

    //2.再调用底层硬件获取本地网关地址信息
    static string GetGateWayAddress()
    {  
        ManagementObjectCollection moc = new ManagementClass("Win32_NetworkAdapterConfiguration").GetInstances();
        foreach (ManagementObject mo in moc)  
        {       
            foreach (PropertyData p in mo.Properties)
                {    
                if (p.Name.Equals("DefaultIPGateway") && (p.Value != null))   
                    {              
                    string[] strs = p.Value as string[]; 
                    string[] CS$6$0004 = strs;        
                    int CS$7$0005 = 0;          
                    while (CS$7$0005 < CS$6$0004.Length) 
                        {                   
                            return CS$6$0004[CS$7$0005];
                        }      
                }      
            }  
        }  
        return "";
    }
     

    //3.分别向本地网关内机器发送ICMP数据包

    bool Pinging(string addr, int id, uint taskid)

        try 
        {      
            this.m_id = id; 
            this.m_taskid = taskid;
            byte[] byReq = this.FillEchoReq();
            IPEndPoint lep = new IPEndPoint(IPAddress.Parse(addr), 0);  
            this.socket.SendTo(byReq, lep);   
        }  
        catch (Exception e) 
            {  
            Console.WriteLine("Send error:" + e.ToString()); 
            return false; 
        }  
        return true;
    }
     
    //4.定义本地机器节点信息类

    public class LocalMachine

        // Fields   
        private string machineIP;
        private string machineMAC; 
        private string machineName;
       
        // Methods   
        public LocalMachine();   
        // Properties   
        public string MachineIP     { get; set; }  
        public string MachineMAC { get; set; } 
        public string MachineName { get; set; }
    }
    //5.根据arp原理,最后通过以下方式读取arp列表节点信息,其实这里还可以IMCP包响应来获取主机响应,
    //不过我个人认为用直接读取列表的方式更加快速有效。
    static ArrayList GetAllLocalMachines()
    {  
        Process p = new Process();
        p.StartInfo.FileName = "cmd.exe"; 
        p.StartInfo.UseShellExecute = false; 
        p.StartInfo.RedirectStandardInput = true;  
        p.StartInfo.RedirectStandardOutput = true; 
        p.StartInfo.RedirectStandardError = true;   
        p.StartInfo.CreateNoWindow = true;  
        p.Start();
        p.StandardInput.WriteLine("arp -a");
        p.StandardInput.WriteLine("exit"); 
        ArrayList list = new ArrayList();  
        StreamReader reader = p.StandardOutput;
        string IPHead = Dns.GetHostByName(Dns.GetHostName()).AddressList[0].ToString().Substring(0, 3);
        for (string line = reader.ReadLine(); line != null; line = reader.ReadLine()) 
        {      
            line = line.Trim();     
            if (line.StartsWith(IPHead) && (line.IndexOf("dynamic") != -1))
                {           
                string IP = line.Substring(0, 15).Trim();       
                string Mac = line.Substring(line.IndexOf("-") - 2, 0x11).Trim();
                LocalMachine localMachine = new LocalMachine();           
                localMachine.MachineIP = IP;      
                localMachine.MachineMAC = Mac;      
                localMachine.MachineName = "";         
                list.Add(localMachine);     
            }  
        }  
        return list;
    }

    //6.最后,你还可以通过以下方法来获取网卡的MAC地址信息
    [DllImport("NETAPI32.DLL")]
    public static extern char Netbios(ref MACAddress.NCB ncb);

    public string GetMacAddress()
    {   
        string addr = ""; 
        try 
        {     
            NCB Ncb = new NCB();  
            Ncb.ncb_command = 0x37; 
            int cb = Marshal.SizeOf(typeof(LANA_ENUM));   
            Ncb.ncb_buffer = Marshal.AllocHGlobal(cb);   
            Ncb.ncb_length = (ushort) cb;   
            char uRetCode = Win32API.Netbios(ref Ncb); 
            LANA_ENUM lenum = (LANA_ENUM) Marshal.PtrToStructure(Ncb.ncb_buffer, typeof(LANA_ENUM));   
            Marshal.FreeHGlobal(Ncb.ncb_buffer);      
            if (uRetCode != '1')
            {}

        }
        catch
        {}
    }

        }

  • 相关阅读:
    【Henu ACM Round#17 A】Simple Game
    【Henu ACM Round #12 E】Thief in a Shop
    【Henu ACM Round#16 D】Bear and Two Paths
    【Henu ACM Round#16 A】 Bear and Game
    P4824 [USACO15FEB]Censoring (Silver) 审查(银)
    P4001 [BJOI2006]狼抓兔子
    P2444 [POI2000]病毒
    P3966 [TJOI2013]单词
    P3796 【模板】AC自动机
    P4574 [CQOI2013]二进制A+B
  • 原文地址:https://www.cnblogs.com/captain_ccc/p/1517413.html
Copyright © 2011-2022 走看看