1、ARP扫描局域网主机ip和MACc# LANScanner Project Report Project No. X Version 1.0 Student ID: 93520081202015 Student Name:银国徽 2010-10-26 College of Computing, CUC I declare that the assignment here submitted is original except for source material explicitly acknowledged. I also acknowledge that I am aware of U
2、niversity policy and regulations on honesty in academic work, and of the disciplinary guidelines and procedures applicable to breaches of such policy and regulations. Name: 银国徽 Student ID:103520430112010 Section I Problem Specification 本次实验的任务是搜索局域网的所有主机,获取其MAC,并能时刻获取主机是否开机的信息。要求采用可视化界面进行设计。 Section
3、 II Solution Method and Design 第一步:获取本机IP和本机所在局域网网段的子网掩码sub-mask; 第二步:写一个算法,根据上一步的信息获取整个网段所有的IP,尽量避免进行简单的与运算,因为当子网掩码为非255.255.255.0时,计算量非常大,为了使程序获得更快的速度和稳定性,需要一个小技巧。原理很简单:一个网段的IP总是连续的。利用这个原理可以大大简化计算。举例如下: 本机的IP是10.128.9.230,子网掩码为255.255.252.0; 那么本网段的可用IP范围是10.128.8.0-10.128.11.255。这里面的规律是很有趣的,大家可以算算
4、看。 第三步:利用上步所得的结果构造ARP包,获取相应的MAC; 第四步:利用多线程技术,快速实现ARP的运行; 第五步:将返回的结果利用委托技术显示到主窗口上。 Section III Test Cases and Results Analysis Section IV Conclusion 通过本次实验,我对C#、多线程、委托、整个程序的运行次序有了更深入的理解,感谢老师给予的指导,我会通过学习C#了解C+的运行方式,因为他们的模式太相似了。 Section V References C#多线程计算机扫描 电脑爱好者 C#.net实训编程 XX文库 C# 如何理解多线程和委托 XX文库 C
5、# 数据类型转换 XX文库 C+和C#互调用DLL 豆丁文档 C# raw socket 网络封包监视 CSDN Section VI Appendix using System; using System.Management; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.T
6、hreading;/使用多线程的声明(准确的说是要在main主线程中建立新的线程时要进行的引用说明) using System.Runtime.InteropServices;/使用DllImport的空间引用声明 using System.Net;/对IP相关类的引用声明 namespace mytest public partial class Form1 : Form DllImport(Iphlpapi.dll) public static extern uint SendARP(uint DestIP, uint SrcIP, ref ulong pMacAddr, ref uint
7、 PhyAddrLen); public static int Num = 0; byte submask=0,0,0,0; byte localip = 0,0,0,0; byte netip = 0,0,0,0; int temp=0,0,0,0; byte destip = 0,0,0,0; public static string IP; public static string Mac; public static string ItemFlag; /Thread thread1; /在主线程中声明线程1 / Thread thread2; /在主线程中声明线程2 delegate
8、void daililist();/主线程之外的线程要调用main线程中建立的控件,需要使用委托的方式,此处是委托的定义 public delegate void UpdateList(string ip,string result); public delegate void UpdateLabel(); /daililist list1;/委托实例化,即建立委托对应的事件 public Form1() InitializeComponent(); /list1 = new daililist(updatelist);/委托处理的方法,这里updatelist是一个方法,这个句子的意思是把u
9、pdatelist这个方法交给了list1这个委托实例 button2.Enabled = false; button4.Enabled = false; private void button1_Click(object sender, EventArgs e) /*thread1 = new Thread(numadd ); thread2 = new Thread(numadd); thread1.Start(); thread2.Start();*/ /listBox1.Items.Add(GetMac(10.128.11.254); label6.Text = 系统正在搜索,请等待.
10、; baseinfo(listBox1,listBox2 ); GetDestIp(localip ,submask ,listBox3 ); label5.Text =当前网段内可用的IP共+listBox3 .Items.Count.ToString ()+种! ; button1.Enabled = false; button4.Enabled = true; label6.Text = 系统搜索完毕!; public void baseinfo(ListBox s1,ListBox s2)/获取本机ip、子网掩码、本段网络号基本信息 ManagementClass mc = new M
11、anagementClass(Win32_NetworkAdapterConfiguration); ManagementObjectCollection nics = mc.GetInstances(); foreach (ManagementObject nic in nics) if (Convert.ToBoolean(nicipEnabled) = true) s1.Items.Add(nicIPAddress as String)0); s2.Items.Add(nicIPSubnet as String)0); s1.SelectedIndex = 0;/选中ip列表首选项 s2
12、.SelectedIndex = 0;/选中mask列表首选项 IPAddress ip = IPAddress.Parse(s1.SelectedItem.ToString();/将ip字符串格式转换成ip格式 localip = ip.GetAddressBytes();/将ip格式转换成字节数组,便于运算 ip = IPAddress.Parse(s2.SelectedItem.ToString();/将子网掩码 submask = ip.GetAddressBytes(); netip = NetIPDeal(localip ,submask ); public byte NetIPD
13、eal(byte localip, byte submask)/获取网络号 byte result=0,0,0,0; int temp = 0,0,0,0; for (int i = 0; i 4; i+) tempi = (int)localipi & (int)submaski; resulti = (byte)tempi; return result; public void GetDestIp(byte localip,byte submask,ListBox ResultShow)/获取网段IP,只要给定本机IP和子网掩码,可以迅速确定网段所有IP int interval=0,0,
14、0,0;/存储本网段子网掩码和全掩码(255.255.255.255)的码距 byte top = 0,0,0,0;/记录本网段可用IP的上限IP byte bottom = 0, 0, 0, 0 ;/记录本网段可用IP的下限IP byte netip = 0,0,0,0;/存贮临时的网络号 for (int i = 0; i 4; i+)/计算本网段子网掩码和全掩码(255.255.255.255)的码距 if (submaski != 255) intervali = 255 - (int)submaski+1; netip = NetIPDeal(localip ,submask );
15、byte temp; for (int i = 0; i 4; i+) temp = localipi; if (intervali != 0) int temp_result; temp_result = (int)temp & (int)(submaski); if (intervali != 256) while (temp_result = (int)netipi) temp+; temp_result = (int)temp & (int)(submaski); topi = (byte)(int)temp - 1); bottomi = (byte)(int)topi - inte
16、rvali + 1); else topi = 254; bottomi = 0; else topi = (byte)temp; bottomi = topi; for (byte i = bottom0; i = top0; i+) for (byte j = bottom1; j = top1; j+) for (byte k = bottom2; k = top2; k+) for (byte t = bottom3; t = top3; t+) string dest; dest = i.ToString() + . + j.ToString() + . + k.ToString()
17、 + . + t.ToString(); ResultShow.Items.Add(dest); /* public void updatelist() listBox4.Items.Add(Num); */ /* public void numadd() Num+; listBox4.Invoke(list1);/这是自己建立的线程要调用的方法,但是listbox1是main主线程建立的控件,自定义的线程无法直接访问,上面已经定义了委托,此处应用listbox1的invoke /方法把所有对listbox1的操作都交给委托list1去处理。 /到此我们理一下思路,建立线程thread1、th
18、read2,这两个线程都指向了numadd这个方法,首先都执行Num+,然后执行listBox1.Invoke(list1),意思是说将要对listbox1操作, /但是具体操作在list1这个委托当中,然后这个委托指向了updatelist并执行,至此thread1、thread2都完成了对listbox1的操作! */ /* public static string GetMac(string p_Id) IPAddress _Address; if (!IPAddress.TryParse(p_Id, out _Address) return ; uint DestIP = System
19、.BitConverter.ToUInt32(_Address.GetAddressBytes(), 0); ulong pMacAddr = 0; uint PhyAddrLen = 6; uint error_code = SendARP(DestIP, 0, ref pMacAddr, ref PhyAddrLen); byte _Bytes1 = BitConverter.GetBytes(pMacAddr); return BitConverter.ToString(_Bytes1, 0, 6); */ void UpdateMyLabel() / label6.Text = 系统正
20、在搜索,请等待.; void UpdateMyList(string ip,string result)/委托入口程序 lock (listBox4) if (result!=ItemFlag ) listBox4.Items.Add(ip+ MAC +result); ItemFlag = result; / progressBar1.Value+; public void GetMac() IPAddress _Address; if (!IPAddress.TryParse(IP, out _Address) return; uint DestIP = System.BitConvert
21、er.ToUInt32(_Address.GetAddressBytes(), 0); ulong pMacAddr = 0; uint PhyAddrLen = 6; UpdateList showmac = new UpdateList(UpdateMyList); UpdateLabel upmylabel = new UpdateLabel(UpdateMyLabel); try/捕获程序异常 uint error_code = SendARP(DestIP, 0, ref pMacAddr, ref PhyAddrLen);/发送ARP包,获取MAC byte _Bytes1 = B
22、itConverter.GetBytes(pMacAddr); Mac = BitConverter.ToString(_Bytes1, 0, 6); catch Mac = 00-00-00-00-00-00; if (showmac != null) listBox4.Invoke(showmac, IP, Mac);/激活委托,执行委托入口程序 /label5.Invoke(upmylabel ); private void button4_Click_1(object sender, EventArgs e)/扫描给定的IP int count;/获取IP总数,准备建立线程数 int
23、i; button4.Enabled = false;/禁用扫描按钮 count = listBox3.Items.Count; label6.Text = 系统正在扫描,请等待.; Thread myscan = new Threadcount;/定义线程数 for ( i = 0; i count; i+) listBox3.SelectedIndex = i; IP = listBox3.Text; /ygh.showmac = new UpdateList(UpdateMyList ); myscani = new Thread(new ThreadStart(GetMac);/建立线程入口 myscani.Start(); /启动线程 label6.Text = 系统扫描完毕!; button2.Enabled = true; private void button2_Click(object sender, EventArgs e)/清除四个列表信息 listBox1.Items.Clear(); listBox2.Items.Clear(); listBox3.Items.Clear(); listBox4.Items.Clear(); button1.Enabled = true; button2.Enabled = false;
copyright@ 2008-2023 冰点文库 网站版权所有
经营许可证编号:鄂ICP备19020893号-2