一、计算机网络基础
这一点毋庸置疑,想要写一个使用网络接口传输数据的程序,不知道计算机网络的基本知识是很难的。
局域网与广域网
所谓的WAN和LAN其实就是网络的一个范围界定。WAN为广域网,中间会包含更多的互联网设备,由无数个局域网组成。LAN局域网应该更加令人熟悉,因为我们日常生活中建立家庭网络环境,搭建路由器,配置网络环境,乃至于使用虚拟机,都会听到这样一个词。
那么我们的网络编程技术就要涉及到网络协议的部分,所谓网络协议就是规定了计算机之间连接的物理、机械、电气等特征。
局域网内一般是比较好测试的环境,因为此时你的设备一般离你比较近,甚至都是你家庭内的设备,但是涉及到广域网乃至于整个互联网,此时就需要比较复杂的网络协议才能维持运作。
我们今天提到这一概念的目的并不是要学习计算机网络,而是为我们代码中要用到的角色做个铺垫。IP,DNS,TCP,UDP,大家都了解多少呢?
IP是什么相信大家或多或少了解过,总而言之,这是一台计算机,在当前网络下的身份证号或者说门牌号,是和同一个网络环境乃至于不同网络环境通信的关键。
TCP是一种可靠连接的数据通信协议,运行在传输层,与之相比哈游一种不可靠,无连接的传输协议UDP。
DNS是域名解析服务,domain name system,是根据给到的网址域名寻找对应计算机的服务。除此之外还有很多基础协议类似于路由协议中的内部网关协议和外部网关协议等等。
端口和套接字
端口
在了解了基础的网络通讯基础和条件之后我们就来认识一个概念:端口。
如果说我们互联网世界IP对应一个房子的门牌号的话,当数据包到达我的计算机防火墙等等的地方,该怎么进入我们的房子呢?此时就会用到我们的端口(门)了,端口是从0到65535的一个取值的数字,也就是说我们在找到房子之后,还要找到对的门进入。其中0-1023的数字被保留用于一些比较知名的网络服务和应用,所以我们要避开冲突,除此之外,我们应当给应用程序预留一段可以使用的范围或者允许用户自定义而不是只在一个端口上提供服务,这对我们程序兼容性能以及宣传起步是十分不利的。
当我们写了一个程序监听了我们的端口之后,相当于我们就拥有了提供服务的条件。
套接字是什么
socket这一词在英文中翻译过来意味着插座,在我们网络通信中,这一概念理解为两台计算机中间的一种连线。既然我们刚刚说过了,计算机建立连接需要端口,那么连接建立成功之后像不像一条线插在插座上呢。因为我们访问一个端口建立连接也是需要使用本地端口发出的。
四元组
源ip:源端口:目的ip:目的端口
这四个元素组成的组合决定了一个TCP连接,一般我们建立连接只需要确定目标ip和目标端口就可以,操作系统会分配对应的端口给程序,对于linux而言,还有文件描述符用于读写数据。
所以限制TCP连接的数目并不是端口数,而是与端口数有关的一系列更大的数字和条件。
二、C#中与IP相关的类
DNS类
Dns 类 (System.Net) | Microsoft Learn
最重要的几个方法:
在下面代码中展示了
- 如何获取对应主机ip,
- 如何通过ip获取主机名,
- 如何通过ip或者主机名获得对方的IPHostEntry实例。
- 获取本地的主机名
using System.Net;
//返回指定主机ip
IPAddress[] ips=Dns.GetHostAddresses("www.baidu.com");
//返回对应ip或者主机名的IPhostEntry实例
IPHostEntry iPHostEntry = Dns.GetHostEntry("www.baidu.com");
//获得本地主机名
string myhostname = Dns.GetHostName();
//解析刚刚获得的hostentry
string hostName = iPHostEntry.HostName;
IPAddress[] addressList = iPHostEntry.AddressList;
string[] aliases = iPHostEntry.Aliases;
//
//弃用的
//IPHostEntry dnssig=Dns.GetHostByName("dreamer");
Console.WriteLine("www.baidu.com s'IpHostEntry:\n IP Addresses:");
foreach (IPAddress ip in ips)
{
Console.WriteLine(ip.ToString());
}
Console.WriteLine("\n主机名(Host Name): \n" + hostName);
Console.WriteLine("Address List:");
foreach (IPAddress address in addressList)
{
Console.WriteLine(address.ToString());
}
Console.WriteLine("别名(Aliases):");
foreach (string alias in aliases)
{
Console.WriteLine(alias);
}
Console.WriteLine("\n我的主机名(My Host Name): \n" + myhostname);
Console.WriteLine();
IPAddress类
顾名思义,这一个类的作用主要就是用来提供ip地址,其中包含一系列预设的属性和方法。
IPAddress 类 (System.Net) | Microsoft Learn
下面的代码中介绍了转化ip字符串为IPAddress实例的方法等等:
- 转化ip为IPAddress实例,
- 转化一个数字为ip实例,
- 转化地址为字节数组
字段中包括:
- 代表全部监听的地址
- 环回地址
- 广播地址
- 代表任意IPV6地址
- IPv6环回地址
- 以及两个none地址
// 方法
IPAddress exip1 = IPAddress.Parse("192.168.1.11");
IPAddress exip2;
IPAddress.TryParse("128628", out exip2);
// 字段
IPAddress exip3 = IPAddress.Any;
IPAddress exip4 = IPAddress.Broadcast;
IPAddress exip5 = IPAddress.Loopback;
IPAddress exip6 = IPAddress.IPv6Any;
IPAddress exip7 = IPAddress.IPv6Loopback;
IPAddress exip8 = IPAddress.IPv6None;
IPAddress exip9 = IPAddress.None;
// 非静态方法
byte[] bts = exip1.GetAddressBytes();
// 属性
System.Net.Sockets.AddressFamily af = exip1.AddressFamily;
bool isipv4 = exip1.IsIPv4MappedToIPv6;
bool isipv6 = exip1.IsIPv6LinkLocal;
bool isipv6site = exip1.IsIPv6SiteLocal;
// 输出字段和属性
Console.WriteLine("\n示例 IP 地址 1 (Example IP Address 1): " + exip1.ToString());
Console.WriteLine("示例 IP 地址 2 (Example IP Address 2): " + (exip2 != null ? exip2.ToString() : "无效的 IP 地址"));
Console.WriteLine("Any 地址 (Any Address): " + exip3.ToString());
Console.WriteLine("广播地址 (Broadcast Address): " + exip4.ToString());
Console.WriteLine("Loopback 地址 (Loopback Address): " + exip5.ToString());
Console.WriteLine("IPv6 Any 地址 (IPv6 Any Address): " + exip6.ToString());
Console.WriteLine("IPv6 Loopback 地址 (IPv6 Loopback Address): " + exip7.ToString());
Console.WriteLine("IPv6 None 地址 (IPv6 None Address): " + exip8.ToString());
Console.WriteLine("None 地址 (None Address): " + exip9.ToString());
Console.WriteLine("\n示例 IP 地址 1 的字节数组 (Byte Array of Example IP Address 1): " + BitConverter.ToString(bts));
Console.WriteLine("地址族 (Address Family): " + af.ToString());
Console.WriteLine("是否为 IPv4 映射到 IPv6 (Is IPv4 Mapped to IPv6): " + isipv4);
Console.WriteLine("是否为 IPv6 链接本地地址 (Is IPv6 Link Local): " + isipv6);
Console.WriteLine("是否为 IPv6 站点本地地址 (Is IPv6 Site Local): " + isipv6site);
如图所示,这个类就是用于获取各类IP地址或者对Ip地址进行一些处理的方法。
其他方法可以进入上面的官网查阅文档。
特意注释:address的family属性是什么?其实就是对ip地址进行一个分类。
也就是一个IPv4地址的意思。
IPHostEntry类
这个类非常朴实,用于为我们的IPAddress提供容器类,我们在dns类中获取的的IpHostEntry就是这个类的实例。
IPHostEntry 类 (System.Net) | Microsoft Learn
AddressList
Aliases
HostName
在DNS类中获取的实例就可以解析出上述信息。获取的信息用来干什么呢?什么时候用呢?
那就是后面的内容啦!欢迎大家关注,和大家一起学习。
通过计算机名获取IP地址,通过IP地址获取主机名,