C#之单线程,多线程,线程池程序设计扫描网络IP
单线程,多线程,线程池程序设计扫描网络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:
- 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.cs
- namespace 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;
- }
- }
- }
转载于:https://blog.51cto.com/yang19890314/1124828