博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【转载】用C#获取局域网内所有机器
阅读量:7101 次
发布时间:2019-06-28

本文共 3360 字,大约阅读时间需要 11 分钟。

 

 

如果你使用过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[] str1= strs;        
                int i = 0;          
                while (i< str1.Length) 
                    {                   
                        return str1[i];
                    }      
            }      
        }  
    }  
    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
    {}
}

    }

转载地址:http://tlkhl.baihongyu.com/

你可能感兴趣的文章
正则表达式口诀
查看>>
一个网站故障排查的、代码更新的简便脚本
查看>>
jQuery那坑爹的text()
查看>>
oracle log_archive_dest_1 未指定导致flash_recovery_area引发数据库挂起
查看>>
性能测试培训笔记-安装loadrunner出现vc2005_sp1_with_atl_fix_redist
查看>>
Puppet函数介绍(十八)
查看>>
awk学习笔记之行求和和列求和
查看>>
EtherChannel负载均衡
查看>>
mysql高可用方案之MMM
查看>>
企业级Nginx服务基础到架构优化详解--25条
查看>>
impdp导入数据时出现BUG
查看>>
在执行一个 scripts 时,在 scripts 内的变量, $0, $1 代表什么?
查看>>
Gartner:2016年十大信息安全技术(含解读)
查看>>
BYOD那些事
查看>>
symantec:硝基***针对化工厂商
查看>>
数据中心开发者定义
查看>>
Skype for Business Server 2015-04-前端服务器-0-准备
查看>>
UML与OOAD关系
查看>>
iOS网络编程-ASIHTTPRequest框架同步请求
查看>>
马哥Linux大型免费公开课即将开始(马哥多年经验首次对外公开)
查看>>