用C#获取局域网内所有机器
来源:互联网 发布:孙巍 悦游网络 编辑:程序博客网 时间:2024/06/06 15:46
如果你使用过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);
}
private static extern bool InternetGetConnectedState(out int connectionDescription, int reservedValue);
public static bool IsLocalConnection()
...{
int connectionDescription = 0;
return InternetGetConnectedState(out connectionDescription, 0);
}
2.再调用底层硬件获取本地网关地址信息
3.分别向本地网关内机器发送ICMP数据包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 "";
}
4.定义本地机器节点信息类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;
}
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 != '
- 用C#获取局域网内所有机器
- 用C#获取局域网内所有机器
- 用C#获取局域网内所有机器
- 用C#获取局域网内所有机器
- 用C#获取局域网内所有机器
- 用C#获取局域网内所有IP方法研究
- C#获取局域网内所有数据库服务器
- 获取局域网内所有IP
- 获取局域网内机器名
- c#获取所有局域网IP
- 获取局域网内所有(数据库)SQLServer机器名和实例名
- 获取局域网内所有网络设备MAC地址
- 获取局域网内所有的数据库实例
- java获取局域网内所有ip信息
- Delphi 获取局域网内的机器名
- C#获取局域网内所有的ip及对应的MAC
- 获取局域网内所有可用的SQL Server服务器列表
- DOS获取局域网内所有正在使用的ip地址
- 不用发愁-谈的最大体积
- 在Delphi中如何把数据库中的记录引到word中
- 学习使用
- I
- 由数据库数据生成XML的方法(有源码)
- 用C#获取局域网内所有机器
- Regsvr 32命令详解(DLL、OCX、CPL文件的注册和反注册工具) - NewMap的专栏 - CSDNBlog
- hibernate多表查询
- MYSQL的操作类(修改后的新版本)
- Hibernate多表查询
- 最好的数据导出组件SMExport
- PostgresSQL等大评测
- delphi7从入门到精通之(一)
- C# 文本框只能输入数字和退格键