单线程,多线程,线程池程序设计扫描网络IP

创建一个Windows应用程序,使用多线程等来扫描一个网段内的计算机,根据计算机的IP地址获取其Dns域名,若计算机不在线,则返回提示信息。要求初始界面如图所示。

 

 当用户输入IP地址范围之后,单击【扫描】按钮,程序能自动在listBoxStatus中显示每个IP地址对应的Dns信息。具体要求如下:

(1)对用户选择IP地址范围进行验证,若不是合法的IP地址,给出相应的提示信息。

(2)执行扫描操作时,创建一个线程去扫描一个IP地址。

(3)把每个IP地址对应的Dns信息添加到listBoxStatus中。例如采用“IP地址---Dns域名”形式。

实验要求 

   (1)要求用ipCount表示IP地址的个数;

  (2)要求用start表示IP起始地址,end表示IP终止地址。

2.实验步骤 

  (1)运行Microsoft Visual Studio 2008,创建一个名为ScanComputer的Windows应用程序项目。

  (2)在【解决方案资源管理器】中,设计界面如图1-1所示。

  (3)切换到代码模式,在Form1.cs文件namespace ScanComputer下定义一个委托。

        public delegate void GetComputerDnsDelegate(string strIP,string strHostName);

其中strIP用来表示IP地址,strHostName用来表示IP对应的Dns名字。

  (4)在类Form1.cs中定义并实现方法AddStatusInfoToListBox用来实现向listBoxStatus添加扫描信息。

       方法形式:public void AddStatusInfoToListBox(string strIP, string strHostName)

  (5)为了实现给线程传递多个参数,在namespace ScanComputer下定义一个类Scan,用来保存参数和提供方法实现IP地址到Dns的转换。其中方法CheckComputer实现IP到Dns的转换。

(6)在【扫描】按钮的Click事件中,先判断IP地址范围是否符合要求,然后统计要计算IP的个数,创建多个线程去执行扫描操作。

   程序运行图:

(1)单线程

 

(2)多线程


(3)线程池

 

源程序代码: 

类Scan:

 

 
   
  1. using System; 
  2. using System.Collections.Generic; 
  3. using System.Linq; 
  4. using System.Text; 
  5. using System.Net; 
  6. using System.Windows.Forms; 
  7.   
  8. namespace ScanComputer 
  9.     class Scan 
  10.     { 
  11.         public string strIp; 
  12.         public ScanComputer.Form1.GetComputerDnsDelegate d; 
  13.         public string HostName; 
  14.         public void CheckComputer() 
  15.         { 
  16.             IPAddress ip; 
  17.             IPHostEntry ipe; 
  18.             try 
  19.             { 
  20.                ip = IPAddress.Parse(this.strIp); 
  21.                ipe = Dns.GetHostEntry(ip); 
  22.                HostName = ipe.HostName; 
  23.             } 
  24.             catch 
  25.             { 
  26.                  HostName = "未响应!"
  27.             } 
  28.             if (d != null
  29.             { 
  30.                 d(strIp, HostName); 
  31.             } 
  32.        } 
  33.         public void CheckComputerStr(Object stateInfo) 
  34.         { 
  35.             this.strIp = (string)stateInfo; 
  36.             CheckComputer(); 
  37.         } 
  38.     } 
  39. Form1.cs 
  40. namespace ScanComputer 
  41.     public partial class Form1 : Form 
  42.     { 
  43.         public Form1() 
  44.         { 
  45.             InitializeComponent(); 
  46.         } 
  47.         public int ipCount; 
  48.         public int start; 
  49.         public int end; 
  50.         public string subIP; 
  51.         public int hasEndCount;//用于判断线程是否都已结束 
  52.         public delegate void GetComputerDnsDelegate(string strIP, string strHostName); 
  53.         public void AddStatusInfoToListBox(string strIP, string strHostName) 
  54.         {   
  55.             if (this.listBoxStatus.InvokeRequired) 
  56.             { 
  57.                 GetComputerDnsDelegate d = AddStatusInfoToListBox; 
  58.                 listBoxStatus.Invoke(d,strIP,strHostName); 
  59.             } 
  60.             else 
  61.             {  
  62.                 hasEndCount++;   
  63.                 listBoxStatus.Items.Add(strIP + "---域名:" + strHostName); 
  64.                 if (hasEndCount == ipCount) 
  65.                 { 
  66.                     endTime = DateTime.Now; 
  67.                     TimeSpan tm =endTime - startTime; 
  68.                     listBoxStatus.Items.Add("----------------------"); 
  69.                     listBoxStatus.Items.Add("扫描完毕,用时:" + tm.Milliseconds+"毫秒"); 
  70.                     this.buttonScanSingle.Enabled = true
  71.                     this.buttonScanAgain.Enabled = true
  72.                     this.buttonScanPool.Enabled = true
  73.                 } 
  74.             }  
  75.         } 
  76.         DateTime startTime, endTime; 
  77.         IPAddress ip; 
  78.         IPHostEntry ipe; 
  79.         string strIp, hostName; 
  80.         /// <summary> 
  81.         /// 多线程扫描 
  82.         /// </summary> 
  83.         /// <param name="sender"></param> 
  84.         /// <param name="e"></param> 
  85.         private void buttonScanAgain_Click(object sender, EventArgs e) 
  86.         {  
  87.             Init();//初始化操作  
  88.             if (ipCount < 0) 
  89.             { 
  90.                 MessageBox.Show("起始地址和终止地址有错误,请检查后再次扫描。""提示", MessageBoxButtons.OK, MessageBoxIcon.Question); 
  91.                 return
  92.             }  
  93.             Thread[] scanThreads = new Thread[ipCount]; 
  94.             //定义Scan实例 
  95.             Scan scanObj; 
  96.             for (int i = 0; i < ipCount; i++) 
  97.             { 
  98.                 scanObj = new Scan(); 
  99.                 //传递ip地址 
  100.                 scanObj.strIp = subIP + (numericUpDownIpStart.Value + i).ToString(); 
  101.                 scanObj.d = AddStatusInfoToListBox; 
  102.                 //初始化线程实例 
  103.                 scanThreads[i] = new Thread(scanObj.CheckComputer); 
  104.                 //启动线程 
  105.                 scanThreads[i].Start(); 
  106.              }   
  107.         }  
  108.         /// <summary> 
  109.         /// 单线程 
  110.         /// </summary> 
  111.         /// <param name="sender"></param> 
  112.         /// <param name="e"></param> 
  113.         private void buttonScanSingle_Click(object sender, EventArgs e) 
  114.         {  
  115.             //初始化IP范围 
  116.             Init();  
  117.             if (ipCount <0) 
  118.             { 
  119.                 MessageBox.Show("起始地址和终止地址有错误,请检查后再次扫描。""提示", MessageBoxButtons.OK, MessageBoxIcon.Question); 
  120.                 return
  121.             }  
  122.            Thread thread = new Thread(SingleThread); 
  123.            thread.Start(); 
  124.         }  
  125.         private void SingleThread() 
  126.         { 
  127.             for (int i = 0; i < ipCount; i++) 
  128.             {  
  129.                 strIp = subIP + (numericUpDownIpStart.Value + i).ToString(); 
  130.                 try 
  131.                 { 
  132.                     ip = IPAddress.Parse(strIp); 
  133.                     ipe = Dns.GetHostEntry(ip); 
  134.                     hostName = ipe.HostName; 
  135.                     AddStatusInfoToListBox(strIp, hostName); 
  136.                 } 
  137.                 catch 
  138.                 { 
  139.                     AddStatusInfoToListBox(strIp, "未响应!"); 
  140.                 } 
  141.             } 
  142.         }  
  143.         /// <summary> 
  144.         /// 线程池扫描 
  145.         /// </summary> 
  146.         /// <param name="sender"></param> 
  147.         /// <param name="e"></param> 
  148.         private void buttonScanPool_Click(object sender, EventArgs e) 
  149.         {  
  150.             Init(); 
  151.             Scan scanObj; 
  152.             for (int i = 0; i < ipCount; i++) 
  153.             { 
  154.                 scanObj = new Scan(); 
  155.                 //传递ip地址 
  156.                 scanObj.strIp = subIP + (numericUpDownIpStart.Value + i).ToString(); 
  157.                 scanObj.d = AddStatusInfoToListBox;  
  158.                 //将任务加入线程队列 
  159.                  ThreadPool.QueueUserWorkItem(scanObj.CheckComputerStr, scanObj.strIp);  
  160.             }   
  161.         }  
  162.         /// <summary> 
  163.         /// IP地址范围计算 
  164.         /// </summary> 
  165.         private void Init() 
  166.         { 
  167.             startTime = DateTime.Now; 
  168.             this.listBoxStatus.Items.Clear(); 
  169.             this.buttonScanAgain.Enabled = false
  170.             this.buttonScanSingle.Enabled = false
  171.             this.buttonScanPool.Enabled = false
  172.             subIP = numericUpDownIp1.Value + "." + numericUpDownIp2.Value + "." + numericUpDownIp3.Value+"."
  173.             start = (int)numericUpDownIpStart.Value; 
  174.             end = (int)numericUpDownIpEnd.Value; 
  175.             ipCount = end - start + 1; 
  176.             hasEndCount = 0; 
  177.         }  
  178.     }