http://blog.csdn.net/21aspnet/
如果你使用过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://blog.csdn.net/21aspnet/
如果你使用过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 {} }
}
|
请发表评论