C#編程_單線程IP地址解析

單線程IP地址解析

目標程序

  1. 界面如下圖

image-20200301223944746

  1. 設計方法:完成單個IP地址解析,循環調用方法,完成掃描。
  2. 注意用stopwatch計算時間。

實現思路

  1. 先知道怎麼解析一個單個的IP地址。
  2. 用循環的方法解析多個IP地址。
  3. 設計程序的界面
  4. 設計事件

實現過程

在控制檯中嘗試過程

//實現的思路
//掃描的地址是自己設定的,我們需要設置變量來保存它們。
//掃描的IP地址由兩端組成,一個地址前綴,另外一部分時起始值和終止值
//我們需要輸出的是IP地址,掃描時間,和dns主機名
//IP地址可以由IPAddress.Parse轉換
//可以通過Dns.GetHostEntry來解析
//掃描時間可以用stopwatch來統計
//還需要判斷IP地址是否合法
    string addressPrefix = "127.0.0.";//用來存儲地址前綴
    int startingValue = 1;//存放起始值
    int stopingValue = 2;//存放終止值
 // if (startingValue <= stopingValue && startingValue > 0 &&     startingValue <= 255 && stopingValue > 0 && stopingValue <= 255)
 //{不用if判斷即可
 //用循環來掃描多個IP地址
    for (int i = startingValue; i <= stopingValue; i++)
         {
                string ipString = addressPrefix + i;
                IPAddress ip;//不能直接定義在try裏面,不然出了try就不能用了
                IPHostEntry iPHostEntry;
                string iphostname;
                try//判斷是否合法
                {
                    // IPAddress ip = IPAddress.Parse(ipString);
                    ip = IPAddress.Parse(ipString);
                    //Dns解析
                    //  IPHostEntry iPHostEntry = Dns.GetHostEntry(ip);
                    //  string iphostname = iPHostEntry.HostName;//獲取ip的主機名
                    //  Console.WriteLine($"掃描地址:{ip},掃描用時,主機DNS名稱:{iphostname}");
                    //不能大篇幅的try
                    //要精確點
                }
                catch (Exception ex)
                {
                    Console.WriteLine("IP地址不合法");
                    break;
                }
                Stopwatch sw = new Stopwatch();//實例化一個秒錶對象sw
                sw.Start();//秒錶開始
                try
                { //Dns解析

                    iPHostEntry = Dns.GetHostEntry(ip);
                    iphostname = iPHostEntry.HostName;//獲取ip的主機名
                    sw.Stop();//秒錶結束
                }
                catch (Exception ex)
                {
                    iphostname = "不在線";
                }
              
                long time = sw.ElapsedMilliseconds;//獲取這段過程的時間
                Console.WriteLine($"掃描地址:{ip},掃描用時:{time}毫秒,主機DNS名稱:{iphostname}");
            }
            //string ipString = addressPrefix + startingValue;//拼接成IP地址字符串
            Console.ReadLine();
        }
        /*  else
          {
              Console.WriteLine("IP地址不合法");
              Console.ReadLine();
          }*//

設計WPF界面

<Window x:Class="WpfApp_SingleThreadIPScan.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:WpfApp_SingleThreadIPScan"
        mc:Ignorable="d"
        Title="單線程IP掃描" Height="450" Width="800"
        WindowStartupLocation="CenterScreen">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition />
        </Grid.RowDefinitions>
        <GroupBox Grid.Row="0" Header="掃描的IP地址範圍" VerticalContentAlignment="Center" Padding="10">
            <DockPanel>
                <Label DockPanel.Dock="Left" Content="地址前綴:"/>
                <TextBox Name="txt1" Text="192.168.1."/>
                <Label Content="起始值:" Margin="15 0 0 0"/>
                <TextBox Name="txtStart" Text="102" Margin="0,4,0,0" VerticalAlignment="Top"/>
                <Label Content="終止值:" Margin="15 0 0 0"/>
                <TextBox Name="txtEnd" Text="105"/>
                <Button Name="btn1" Width="60" VerticalAlignment="Center" Content="開始掃描" Click="Button_Click"/>
            </DockPanel>
        </GroupBox>
        <Label Name="labelError" Grid.Row="1" Background="Red" Foreground="White"
              Content="IP地址有錯,請更正!" HorizontalContentAlignment="Center" />
        <GroupBox Grid.Row="2" Header="掃描信息">
            <ListBox x:Name="listBoxInfo"/>
        </GroupBox>
    </Grid>
</Window>

後臺代碼

using System;
using System.Collections.Generic;
using System.Diagnostics;
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 WpfApp_SingleThreadIPScan
{
    /// <summary>
    /// MainWindow.xaml 的交互邏輯
    /// </summary>
    public partial class MainWindow : Window
    {

        public MainWindow()
        {
            InitializeComponent();
            labelError.Visibility = Visibility.Collapsed;//剛開始的時候隱藏報錯的標籤
        }

        private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            string strip1 = txt1.Text + txtStart.Text;
            string strip2 = txt1.Text + txtEnd.Text;
            IPAddress ip1, ip2;
            if (IPAddress.TryParse(strip1, out ip1) == false || IPAddress.TryParse(strip2, out ip2) == false)
            {
                btn1.IsEnabled = false;
                labelError.Visibility = Visibility.Visible;
                return;
            }

            else
            {
                btn1.IsEnabled = true;
                labelError.Visibility = Visibility.Collapsed;
            }

        }
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            int startvalue = int.Parse(txtStart.Text);
            int stopvalue = int.Parse(txtEnd.Text);
            if (startvalue > stopvalue)
            {
                MessageBox.Show("起始值必需大於終止值,地址範圍有誤。請改正!");
            }
            listBoxInfo.Items.Clear();
            string ip = "";
            for (int i = startvalue; i <= stopvalue; i++)
            {
                ip = txt1.Text + i;
                Scan(ip);

            }



        }

        private void Scan(string ip)
        {
            string hostname;
            Stopwatch sw = Stopwatch.StartNew();
            try
            {
                hostname = Dns.GetHostEntry(ip).HostName;
            }
            catch(Exception ex)
            {
                hostname = "(不在線)";
            }
            sw.Stop();
            long time = sw.ElapsedMilliseconds;
            listBoxInfo.Items.Add($"掃描地址:{ip},掃描用時:{time}毫秒,DNS主機名:{hostname}");
        }
    } }

所需要的知識

IP地址

一個IP地址由兩部分組成:

  1. 網絡號:識別該地址所屬的網絡,它由Internet權力機構分配。
  2. 主機號:指明網絡內的主機,它由各個網絡的管理員統一分配。

編址方案:

  1. IPv4編址方案
    • 由4個字節(十進制表示)組成的二進制值進行識別,中間用圓點分開,這種方法叫做點分十進制表示法
  2. IPv6編址方案
    • 每個IP地址有16個字節(128位二進制數),其完整格式用8段16進製表示,各段之間用冒號分隔。

子網掩碼

​ 子網掩碼用於屏蔽IP地址的一部分以區別網絡標識和主機標識。子網掩碼把所有的網絡位(二進制)用1來標識,主機位用0來標識

  • 例如:如果將子網掩碼設置爲255.255.255.0,則對於IP地址192.168.1.X,其網絡標示部分爲192.168.1;主機標示爲:X

可以利用子網掩碼判斷兩臺計算機是否在同一子網內.

  • 將其IP地址和子網掩碼做按位與運算,如果得到結果相同即在同一個子網內。

端口

image-20200301230615579

  • 物理上的端口。如ADSL Modem、集線器的接口。
  • 邏輯意義上的端口,即進程標識
    • 端口號的範圍從0到65535
    • 1000以內的端口號大多被標準協議所佔用,所以應用程序中可以自由使用的端口號一般都使用大於1000的值。如寶塔面板的8888端口。

C#中關於IP地址轉換的類

  • 提供網際協議IP地址的IPAddress類;
  • 包含IP地址和端口號的IPEndPoint類;
  • 爲Internet或Intranet主機提供信息容器的IPHostEntry類。

IPAddress類

  • 位於System.Net命名空間
  • 提供了對IP地址的轉換和處理功能

Parse方法:將IP地址字符串轉換爲IPAddress的實例。

 IPAddress ipa = IPAddress.Parse(ip);//把IP字符串轉換爲IPaddress類型

但如果該字符串不是IP地址類型,會出現異常。所以我們需要進行異常處理。

System.FormatException:“指定了無效的 IP 地址。”

所以一般我們這樣用:

  string ip = "127.0.0.1";//定義一個IP字符串
            //IPAddress ipa = IPAddress.Parse(ip);//把IP字符串轉換爲IPaddress類型
            try
            {
                IPAddress ipa = IPAddress.Parse(ip);
            }
            catch
            {
                Console.WriteLine("請輸入正確的IP地址!");
                Console.ReadLine();
            }
AddressFamily屬性
 //AddressFamily
            IPAddress ip = IPAddress.Parse("::1");
            IPAddress ip1 = IPAddress.Parse("127.0.0.1");
            if (ip.AddressFamily == AddressFamily.InterNetworkV6)
            {
                Console.WriteLine("該IP地址採用IPV6編址");
                Console.ReadLine();
            }

IPAddress類還提供了7個只讀字段,分別代表程序中使用的特殊IP地址。

常見只讀字段

Any 提供一個IPv4地址,指示服務端應偵聽所有網絡接口上的客戶端活動,它等效於0.0.0.0
Broadcast 提供IPv4網絡廣播地址,它等效於255.255.255.255
IPv6Any 提供所有可用的IPv6地址
IPv6Loopback 表示系統的IPv6迴環地址,等效於::1
Loopback 表示系統的IPv4迴環地址,等效於127.0.0.1
IPEndPoint類
  • 應用程序連接到主機上的服務所需的主機和端口信息。
  • 常用構造函數
IPAddress localAdress = IPAddress.Parse("127.7.0.1");
            IPEndPoint iep = new IPEndPoint(localAdress, 21);//初始化IPEndPoint類
            string ipaddress = "IP地址爲"+iep.Address;//此處利用拼接字符串把IPAddress轉換爲字符串型
            string port = "端口號爲" + iep.Port;
            Console.WriteLine($"{ipaddress}\n{port}");
            Console.ReadLine();
IPHostEntry類

​ 將一個域名系統(DNS)的主機名與一組別名和一組匹配的IP地址關聯。該類一般和Dns類一起使用。

域名解析

爲什麼引入域名系統?

  • 網絡主機使用IP地址來定位
  • IP難於記憶,需要用名稱來表示主機
  • IP地址改變後,域名不變,仍可訪問

.NET框架在System.Net命名空間提供了Dns類完成解析

方法名稱
GetHostAddresses 返回指定主機的Internet協議IP地址與該方法對應的還有異步方法
GetHostEntry 將主機名或IP地址解析爲IPHostEntry實例該方法對應的還有異步方法
GetHostName 獲取本地計算機的主機名
GetHostAddresses方法

指定主機的IP地址,返回一個IPAddress類型的數組。

  • public static IPAddress[] GetHostAddresses(string hostNameOrAddress);
    • 參數中的hostNameOrAddress表示要解析的主機名或IP地址。
  • 若hostNameOrAddress是IP地址,則直接返回此地址;若是空字符串,則返回本機所有IPv4和IPv6地址。
IPAddress[] ips = Dns.GetHostAddresses("baidu.com"); //定義一個數組來存放從主機來解析的IPAddress類
            IPAddress[] ips1 = Dns.GetHostAddresses("www.cctv.com");
            IPAddress[] ips2 = Dns.GetHostAddresses("127.0.0.1");//若hostNameOrAddress是IP地址,則直接返回此地址;
            IPAddress[] ips3 = Dns.GetHostAddresses("");//若是空字符串,則返回本機所有IPv4和IPv6地址。
          
            foreach (var i in ips3)
            {
                Console.WriteLine(i);

            }
            Console.ReadLine()
GetHostEntry方法

根據主機名或IP地址返回一個IPHostEntry實例,用於在DNS服務器中查詢與某個主機名或IP地址關聯的IP地址列表。

  • public static IPHostEntry GetHostEntry (string hostNameOrAddress)
  • hostNameOrAddress表示要解析的主機名或IP地址
  • 當參數爲空字符串時,返回本地主機的IPHostEntry實例。
 IPHostEntry iPHostEntry = Dns.GetHostEntry("");
            var iplist = iPHostEntry.AddressList;//獲取IP地址列表
            var hostname = iPHostEntry.HostName;//獲取主機名
            foreach(var i in iplist)
            {
                Console.WriteLine(i);
            }
            Console.WriteLine($"主機名字爲{hostname}");
            Console.ReadLine();
GetHostName方法

該方法用於獲取本機主機名。

 string hostname = Dns.GetHostName();
            Console.WriteLine($"本機的主機名爲:{hostname}");
            Console.ReadLine();
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章