網段掃描練習
創建一個WPF應用程序,分別用多線程/線程池/多任務來掃描一個網段內的計算機,根據計算機的IP地址獲取其主機域名。
涉及到相關的知識點:練習IPAddress類、Dns類和IPHostEntry類的基本用法,練習WPF應用程序中多線程編程的基本用法,練習多任務編程。
MainActivity.xaml
<Window x:Class="網段掃描練習.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:網段掃描練習"
mc:Ignorable="d"
Title="網段掃描" Height="450" Width="800">
<Grid>
<GroupBox x:Name="groupBox" Header="掃描的IP地址範圍" HorizontalAlignment="Left" Margin="34,22,0,0" VerticalAlignment="Top" Height="95" Width="637" BorderThickness="3">
<Grid HorizontalAlignment="Left" Height="77" Margin="10,0,0,-4" VerticalAlignment="Top" Width="600">
<Label x:Name="label1" Content="地址前綴:" HorizontalAlignment="Left" Margin="19,26,0,0" VerticalAlignment="Top"/>
<Label x:Name="label2" Content="起始值:" HorizontalAlignment="Left" Margin="184,28,0,0" VerticalAlignment="Top"/>
<Label x:Name="label3" Content="終止值:" HorizontalAlignment="Left" Margin="338,28,0,0" VerticalAlignment="Top"/>
<TextBox x:Name="textBox1" HorizontalAlignment="Left" Margin="93,30,0,0" TextWrapping="Wrap" Text="請輸入" VerticalAlignment="Top" Width="86" Height="20" Background="#FFBBB5B5"/>
<TextBox x:Name="textBox2" HorizontalAlignment="Left" Margin="238,30,0,0" TextWrapping="Wrap" Text="請輸入" VerticalAlignment="Top" RenderTransformOrigin="2.389,0.574" Width="86" Height="20" Background="#FFBBB5B5"/>
<TextBox x:Name="textBox3" HorizontalAlignment="Left" Margin="392,30,0,0" TextWrapping="Wrap" Text="請輸入" VerticalAlignment="Top" RenderTransformOrigin="2.389,0.574" Width="86" Height="20" Background="#FFBBB5B5"/>
<Button x:Name="begin" Content="開始掃描" HorizontalAlignment="Left" Margin="505,28,0,0" VerticalAlignment="Top" Width="75"/>
</Grid>
</GroupBox>
<GroupBox x:Name="groupBox1" Header="掃描信息" HorizontalAlignment="Left" Margin="34,145,0,0" VerticalAlignment="Top" Height="157" Width="637" BorderThickness="3">
<ListBox x:Name="listBox" HorizontalAlignment="Left" Height="131" VerticalAlignment="Top" Width="627" Margin="0,0,-2,0"/>
</GroupBox>
<Label x:Name="error" Content="IP地址有錯,請更正!" HorizontalAlignment="Left" Margin="0,122,0,0" VerticalAlignment="Top" Width="681" Background="#FFD43939" Foreground="#FFF3ECEC" Visibility="Hidden" HorizontalContentAlignment="Center"/>
</Grid>
</Window>
MainActivity.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace 網段掃描練習
{
/// <summary>
/// MainWindow.xaml 的交互邏輯
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
begin.Click += Begin_Click;
}
//創建兩個IPAddress的對象,分別用來保存開始的IP地址和結束的IP地址
IPAddress IpStart, IpEnd;
//開始掃描按鈕點擊事件方法
private async void Begin_Click(object sender,RoutedEventArgs e)
{
//將listbox控件清空
listBox.Items.Clear();
String input1 = textBox1.Text;
String input2 = textBox2.Text;
String input3 = textBox3.Text;
int int_input2;
int int_input3;
//將第二個輸入框的內容轉化爲int類型
int_input2 = int.Parse(input2);
//將第三個輸入框的內容轉化爲int類型
int_input3 = int.Parse(input3);
int count = 0;//計數器
int k = input1.Length;//記錄input1的長度
//判斷第一個輸入框有沒有在最後加'.',若沒有則補上(代碼的健壯性)
if (!input1[k - 1].Equals('.'))
{
input1 = input1 + '.';
}
//將輸入的內容進行拼接並轉化爲地址,判斷第二個輸入框是否小於第三個輸入框
//如果不能正確的轉化爲IP地址或者第二個框內容不小於第三個框,顯示錯誤提示信息
if(IPAddress.TryParse(input1+input2,out IpStart) && IPAddress.TryParse(input1 + input3, out IpEnd) && (int_input2 <= int_input3))
{
count = int_input3 - int_input2 + 1;
tips_hidden();//輸入正確,隱藏錯誤提示信息
}
else
{
tips();//輸入錯誤,顯示錯誤提示信息
}
for(int i = 0; i < count; i++)
{
String ipString = input1 + (int.Parse(input2) + i);
IPAddress ip = IPAddress.Parse(ipString);
await Task.Run(() => scan(ip));
// scan(ip); //主線程
/*Thread t = new Thread(scan); 多線程
t.Start(ip); 多線程*/
//Task.Run(() => scan(ip));//多任務
//ThreadPool.QueueUserWorkItem(new WaitCallback(scan), ip);//線程池
}
}
public void tips()//顯示輸入錯誤的信息
{
error.Visibility = Visibility.Visible;
}
public void tips_hidden()//隱藏輸入錯誤提示信息
{
error.Visibility = Visibility.Hidden;
}
public void scan(Object ip)//掃描方法並記錄掃描時間
{
DateTime timeBegin = DateTime.Now;//記錄開始時間
IPAddress iPAddress = (IPAddress)ip;//強制類型轉換
String hostName;//主機名
try
{
hostName = Dns.GetHostEntry(iPAddress).HostName;//通過DNS獲取主機名
}
catch (Exception e)
{
hostName = "(不在線)";
}
DateTime timeEnd = DateTime.Now;//記錄結束時間
TimeSpan timeSpan = timeEnd - timeBegin;//時間間隔
//WPF調度器 裏面是lambda表達式
listBox.Dispatcher.Invoke(() => listBox.Items.Add("掃描地址:" + ip + "," + "掃描時間:" + timeSpan.Milliseconds + "毫秒," + "主機DNS名稱:" + hostName));
}
}
}