oLeiShen 2020-03-05
?
//实现的思路 //扫描的地址是自己设定的,我们需要设置变量来保存它们。 //扫描的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(); }*//
<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来标识,主机位用0来标识。
可以利用子网掩码判断两台计算机是否在同一子网内.
IPAddress类
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 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 |
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();
? 将一个域名系统(DNS)的主机名与一组别名和一组匹配的IP地址关联。该类一般和Dns类一起使用。
为什么引入域名系统?
.NET框架在System.Net命名空间提供了Dns类完成解析
方法名称 | 说 明 |
---|---|
GetHostAddresses | 返回指定主机的Internet协议IP地址与该方法对应的还有异步方法 |
GetHostEntry | 将主机名或IP地址解析为IPHostEntry实例该方法对应的还有异步方法 |
GetHostName | 获取本地计算机的主机名 |
指定主机的IP地址,返回一个IPAddress类型的数组。
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()
根据主机名或IP地址返回一个IPHostEntry实例,用于在DNS服务器中查询与某个主机名或IP地址关联的IP地址列表。
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();
该方法用于获取本机主机名。
string hostname = Dns.GetHostName(); Console.WriteLine($"本机的主机名为:{hostname}"); Console.ReadLine();