建立一個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終止地址。
5.實驗步驟
(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)線程池
來源程式:
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Net;using System.Windows.Forms; namespace ScanComputer{ class Scan { public string strIp; public ScanComputer.Form1.GetComputerDnsDelegate d; public string HostName; public void CheckComputer() { IPAddress ip; IPHostEntry ipe; try { ip = IPAddress.Parse(this.strIp); ipe = Dns.GetHostEntry(ip); HostName = ipe.HostName; } catch { HostName = "未響應!"; } if (d != null) { d(strIp, HostName); } } public void CheckComputerStr(Object stateInfo) { this.strIp = (string)stateInfo; CheckComputer(); } }}Form1.csnamespace ScanComputer{ public partial class Form1 : Form { public Form1() { InitializeComponent(); } public int ipCount; public int start; public int end; public string subIP; public int hasEndCount;//用於判斷線程是否都已結束 public delegate void GetComputerDnsDelegate(string strIP, string strHostName); public void AddStatusInfoToListBox(string strIP, string strHostName) { if (this.listBoxStatus.InvokeRequired) { GetComputerDnsDelegate d = AddStatusInfoToListBox; listBoxStatus.Invoke(d,strIP,strHostName); } else { hasEndCount++; listBoxStatus.Items.Add(strIP + "---網域名稱:" + strHostName); if (hasEndCount == ipCount) { endTime = DateTime.Now; TimeSpan tm =endTime - startTime; listBoxStatus.Items.Add("----------------------"); listBoxStatus.Items.Add("掃描完畢,用時:" + tm.Milliseconds+"毫秒"); this.buttonScanSingle.Enabled = true; this.buttonScanAgain.Enabled = true; this.buttonScanPool.Enabled = true; } } } DateTime startTime, endTime; IPAddress ip; IPHostEntry ipe; string strIp, hostName; /// <summary> /// 多線程掃描 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void buttonScanAgain_Click(object sender, EventArgs e) { Init();//初始化操作 if (ipCount < 0) { MessageBox.Show("起始地址和終止地址有錯誤,請檢查後再次掃描。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Question); return; } Thread[] scanThreads = new Thread[ipCount]; //定義Scan執行個體 Scan scanObj; for (int i = 0; i < ipCount; i++) { scanObj = new Scan(); //傳遞ip地址 scanObj.strIp = subIP + (numericUpDownIpStart.Value + i).ToString(); scanObj.d = AddStatusInfoToListBox; //初始化線程執行個體 scanThreads[i] = new Thread(scanObj.CheckComputer); //啟動線程 scanThreads[i].Start(); } } /// <summary> /// 單線程 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void buttonScanSingle_Click(object sender, EventArgs e) { //初始化IP範圍 Init(); if (ipCount <0) { MessageBox.Show("起始地址和終止地址有錯誤,請檢查後再次掃描。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Question); return; } Thread thread = new Thread(SingleThread); thread.Start(); } private void SingleThread() { for (int i = 0; i < ipCount; i++) { strIp = subIP + (numericUpDownIpStart.Value + i).ToString(); try { ip = IPAddress.Parse(strIp); ipe = Dns.GetHostEntry(ip); hostName = ipe.HostName; AddStatusInfoToListBox(strIp, hostName); } catch { AddStatusInfoToListBox(strIp, "未響應!"); } } } /// <summary> /// 線程池掃描 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void buttonScanPool_Click(object sender, EventArgs e) { Init(); Scan scanObj; for (int i = 0; i < ipCount; i++) { scanObj = new Scan(); //傳遞ip地址 scanObj.strIp = subIP + (numericUpDownIpStart.Value + i).ToString(); scanObj.d = AddStatusInfoToListBox; //將任務加入線程隊列 ThreadPool.QueueUserWorkItem(scanObj.CheckComputerStr, scanObj.strIp); } } /// <summary> /// IP位址範圍計算 /// </summary> private void Init() { startTime = DateTime.Now; this.listBoxStatus.Items.Clear(); this.buttonScanAgain.Enabled = false; this.buttonScanSingle.Enabled = false; this.buttonScanPool.Enabled = false; subIP = numericUpDownIp1.Value + "." + numericUpDownIp2.Value + "." + numericUpDownIp3.Value+"."; start = (int)numericUpDownIpStart.Value; end = (int)numericUpDownIpEnd.Value; ipCount = end - start + 1; hasEndCount = 0; } }}