IP协议
IP简介
IP协议就是网际协议的核心,所有TCP、UDP、ICMP及IGMP都使用IP数据报格式传输。IP提供的是不可靠、无连接的服务,所谓不可靠是指IP层不保证数据包能成功发送到目标主机,它只管发送,如果发送不成功的话会通过ICMP向发送端报告错误原因;而无连接指的是IP并不维护数据报的连接状态,每个数据报的处理过程是互相独立的。IP 在 TCP/IP 参考模型中处于第三层,也就是网络层。网络层的主要作用是:实现主机与主机之间的通信,也叫点对点通信。当今网络主要包含ipv4和ipv6这两种形式的ip,ipv6是后来新出现的,而ipv4则是如今在大量使用的。
问题: IP(网络层)和MAC(数据链路层)之间有什么区别?
IP 的作用是主机之间通信用的,而 MAC 的作用则是实现直连的两个设备之间通信,而 IP 则负责在没有直连的两个网络之间进行通信传输。举个生活的例子:小林要去一个很远的地方旅行,制定了一个行程表,其间需先后乘坐飞机、地铁、公交车才能抵达目的地,为此小林需要买飞机票,地铁票等。飞机票和地铁票都是去往特定的地点的,每张票只能够在某一限定区间内移动,此处的区间内就如同通信网络中数据链路。在区间内移动相当于数据链路层,充当区间内两个节点传输的功能,区间内的出发点好比源 MAC 地址,目标地点好比目的 MAC 地址。整个旅游行程表就相当于网络层,充当远程定位的功能,行程的开始好比源 IP,行程的终点好比目的 IP 地址。
也就是说,数据在网络中的传输需要网络层和数据链路层的相互配合,没有网络层就不知道“旅游”的起点和终点以及路线,而没有数据链路层那么没有直连的起点和终点就仅仅只是“蓝图”。
IP数据报格式

先主要了解ipv4的数据报:
- 版本:这4 bit规定了数据包的IP协议版本号,通过查看版本号路由器能够确定如何解析IP数据报。
- 首部长度:顾名思义,表示这个IP数据报文的首部数据长度,单位是多少个字节
- 服务区分:用于区分不同的服务类型,比如:实时数据报(网络电话)、非实时流量(FTP)
- 总长度:就是这个IP数据报的总字节长度
- 标识、标志、片偏移:与IP分片相关的三个参数
- 协议:该字段指明了IP数据报的数据部分应交给哪个特定的运输层协议
- 首部校验和:用于帮助路由器检测收到的IP数据报中的比特错误
- 源地址:发送该IP数据报的主机IP地址
- 目标地址:接收该IP数据报的主机IP地址
注意: IP首部字段详见参见:https://zhuanlan.zhihu.com/p/29287795
IPv6 相比 IPv4 的首部改进:
- 取消了首部校验和字段:因为在数据链路层和传输层都会校验,因此 IPv6 直接取消了 IP 的校验。
- 取消了分片/重新组装相关字段:分片与重组是耗时的过程,IPv6 不允许在中间路由器进行分片与重组,这种操作只能在源与目标主机,这将大大提高了路由器转发的速度。
- 取消选项字段:选项字段不再是标准 IP 首部的一部分了,但它并没有消失,而是可能出现在 IPv6 首部中的下一个首部指出的位置上。删除该选项字段使的 IPv6 的首部成为固定长度的 40 字节。
IP地址
在 TCP/IP 网络通信时,为了保证能正常通信,每个设备都需要配置正确的 IP 地址,否则无法实现正常的通信。一般来说,一台主机会有一个ip地址,一台路由器至少具有两个ip地址。IP 地址(IPv4 地址)由 32 位正整数来表示,IP 地址在计算机是以二进制的方式处理的。而人类为了方便记忆采用了点分十进制的标记方式,也就是将 32 位 IP 地址以每 8 位为组,共分为 4 组,每组以“.”隔开,再将每组转换成十进制。注意: 有时候ip地址后面加了一个“/”,比如:192.168.1.1/8,这表示前8位表示网络号

ipv4中IP地址的最大值:
也就说,最大允许大约 43 亿台计算机连接到网络。实际上,IP 地址并不是根据主机台数来配置的,而是以网卡。像服务器、路由器等设备都是有 2 个以上的网卡,也就是它们会有 2 个以上的 IP 地址。
但是其实,能接入网络的主机(电脑、iPad、iPhone…)远远不止43亿台,因为后面网络的发展过程中出现了许多的中间盒,比如:NAT。
IPv4编址
IPv4的编制方式主要是“网络号+主机号”,即前 n 位二进制数表示网络号,后面的 32-n 位二进制数表示主机号。一般来说,n=8、16、32,因此也根据n的值分为A、B、C三类IP地址:
注意: 留意一下这三类地址的前几个比特,他们就是分类的标识。
这3类IP地址可以拥有的最大主机数,如下表所示:
但是,为什么三类地址中,为什么总是比数学上的最大值小2,比如C类地址,数学上的最大值是2^8=256,但是实际的最大值只有256-2=254。
这是因为在 IP 地址中,有两个 IP 是特殊的,分别是主机号全为 1 和 全为 0 地址:
- 主机号全为 1 指定某个网络下的所有主机,即广播地址
- 主机号全为 0 指定某个网络

这里简单介绍一下广播地址:
广播地址用于在同一链路中相互连接的主机之间发送数据包。广播地址可以分为本地广播和直接广播两种:
- 在本网络内广播的广播叫做本地广播:例如网络地址为 192.168.0.0/24 的情况下,广播地址是 192.168.0.255 ,因为这个广播地址的 IP 包会被路由器屏蔽,所以不会到达 192.168.0.0/24 以外的其他链路上。
- 在不同网络之间的广播叫做直接广播:例如网络地址为 192.168.0.0/24 的主机向192.168.1.255/24 的目标地址发送 IP 包。收到这个包的路由器,将数据转发给 192.168.1.0/24,从而使得所有 192.168.1.1~192.168.1.254 的主机都能收到这个包(由于直接广播有一定的安全问题,多数情况下会在路由器上设置为不转发) 。


其实除了A、B、C类地址,IPv4的设计者还预留了两类IP地址,即D、E类IP地址:
但是特别注意 D 类和 E 类地址是没有主机号的,所以不可用于主机 IP,D 类常被用于多播(或称组播),E 类是预留的分类,暂时未使用。而多播就是将数据包发送给特定组内的所有主机。
注意:由于广播无法穿透路由,若想给其他网段发送同样的包,就可以使用可以穿透路由的多播

在IPv4的编址中分为了A、B、C、D、E五类地址,有一定好处,但也有缺点。
好处:不管是路由器还是主机解析到一个 IP 地址时候,我们判断其 IP 地址的首位是否为 0,为 0 则为 A 类地址,后面位依次类推,那么就能很快的找出网络地址和主机地址,如图:
而缺点就是:C类(6万个)地址太少了,而B类(256个)地址又太少了。而为了简介这缺陷,设计者页提出了一些方案,比如不分类(CIDR方案),直接以形式 a.b.c.d/x 表示ip地址,其中 /x 表示前 x 位属于网络号, x 的范围是 0 ~ 32,这就使得 IP 地址更加具有灵活性,如:
注意: CIDR形式没有了前几个特定的比特了,即取消了分类。
随着CIDR方案的应用,即直接划分网络号和主机号,不再进行需要前几个比特的特殊标识来分来,随之也出现了子网掩码这个概念。掩码的意思就是掩盖掉主机号,剩余的就是网络号,将子网掩码和 IP 地址按位计算 AND,就可得到网络号,可以看到子网掩码的作用主要就是根据IP地址得到其所属的网络号。
子网划分
子网划分其实就是把主机号分成“子网网络号+子网主机号”,如图所示:
- 未做子网划分的 ip 地址:网络地址+主机地址
- 做子网划分后的 ip 地址:网络地址+(子网网络地址+子网主机地址)
现假设对 C 类地址进行子网划分,网络地址 192.168.1.0,使用子网掩码 255.255.255.192 对其进行子网划分。C 类地址中前 24 位是网络号,最后 8 位是主机号,根据子网掩码可知从 8 位主机号中借用 2 位作为子网号,如图:
因为子网网络地址被划分成 2 位,那么子网地址就有 4 个,分别是 00、01、10、11,具体划分如下图:




那么为什么要进行子网划分?
随着互连网应用的不断扩大,IP地址资源越来越少,为了实现更小的广播域并更好地利用主机地址中的每一位,可以把基于类的IP网络进一步分成更小的网络,每个子网由路由器界定并分配一个新的子网网络地址,子网地址是借用基于类的网络地址的主机部分创建的。划分子网后,通过使用掩码,把子网隐藏起来,使得从外部看网络没有变化,这也是子网掩码的另一个作用。下面是子网划分的一些优点:
- 减少网络流量
- 提高网络性能
- 简化管理
- 易于扩大地理范围
引入子网后,会有一个共有IP和私有IP的概念:
当我们建立一个局域网时(比如在家里多台机器组成一个局域网,可以共享同一个宽带端口上网,实现局域网内机器之间的数据共享),这时候我们可以使用私有IP作为局域网内机器的IP地址,这个IP地址就是私有IP,私有IP只在所属的局域网内有效,一旦出了所属的局域网就会失效。
注意: 因为私有IP只属于局域网,因此私有IP在不同局域网中可以重复。

私有 IP 地址通常是内部的 IT 人员管理,公有 IP 地址是由 ICANN 组织管理,中文叫互联网名称与数字地址分配机构。IANA 是 ICANN 的其中一个机构,它负责分配互联网 IP 地址,是按州的方式层层分配:
IPv6
IPv4 的地址是 32 位的,大约可以提供 42 亿个地址,但是在 2011 年 IPv4 地址就已经被分配完了。而 IPv6 的地址是 128 位的,这可分配的地址数量是大的惊人, IPv6 甚至可以保证地球上的每粒沙子都能被分配到一个 IP 地址。 IPv6 除了有更多的地址之外,还有更好的安全性和扩展性,说简单点就是 IPv6 相比于 IPv4 能带来更好的网络体验。但是因为 IPv4 和 IPv6 不能相互兼容,所以不但要我们电脑、手机之类的设备支持,还需要网络运营商对现有的设备进行升级,这个工作量是巨大的,所以这是 IPv6 普及率比较慢的原因。
IPv6 地址长度是 128 位,是以每 16 位作为一组,每组用冒号 “:” 隔开。
如果出现连续的 0 时还可以将这些 0 省略,并用两个冒号 “::”隔开。但是,一个 IP 地址中只允许出现一次两个连续的冒号。
IPv6 类似 IPv4,也是通过 IP 地址的前几位标识 IP 地址的种类。IPv6 的地址主要有以下类型地址:
- 单播地址,用于一对一的通信
- 组播地址,用于一对多的通信
- 任播地址,用于通信最近的节点,最近的节点是由路由协议决定
- 没有广播地址

对于一对一通信的 IPv6 地址,主要划分了三类单播地址,每类地址的有效范围都不同。
- 在同一链路单播通信,不经过路由器,可以使用链路本地单播地址,IPv4 没有此类型
- 在内网里单播通信,可以使用唯一本地地址,相当于 IPv4 的私有 IP
- 在互联网通信,可以使用全局单播地址,相当于 IPv4 的公有 IP
IP相关技术
DNS
DNS技术就是根据更加方便人们记忆的域名转换为网际协议的IP,详细文章:
https://www.yuque.com/docs/share/af278527-5363-49cc-b0b2-d0905ba2218d?# 《域名系统》
根域是在最顶层,它的下一层是类似 com 的顶级域,再下面是 server.com。所以域名的层级关系类似一个树状结构:
- 根 DNS 服务器
- 顶级域 DNS 服务器
- 权威 DNS 服务器

下面就是一个域名解析流程:
浏览器首先看一下自己的缓存里有没有,如果没有就向操作系统的缓存要,还没有就检查本机域名解析文件 hosts,如果还是没有,就会 DNS 服务器进行查询,查询的过程如下:
- 客户端首先会发出一个 DNS 请求,问 www.server.com 的 IP 是啥,并发给本地 DNS 服务器(也就是客户端的 TCP/IP 设置中填写的 DNS 服务器地址)。
- 本地域名服务器收到客户端的请求后,如果缓存里的表格能找到 www.server.com,则它直接返回 IP 地址。如果没有,本地 DNS 会去问它的根域名服务器:“老大, 能告诉我 www.server.com 的 IP 地址吗?” 根域名服务器是最高层次的,它不直接用于域名解析,但能指明一条道路。
- 根 DNS 收到来自本地 DNS 的请求后,发现后置是 .com,说:“www.server.com 这个域名归 .com 区域管理”,我给你 .com 顶级域名服务器地址给你,你去问问它吧。”
- 本地 DNS 收到顶级域名服务器的地址后,发起请求问“老二, 你能告诉我 www.server.com 的 IP 地址吗?”
- 顶级域名服务器说:“我给你负责 www.server.com 区域的权威 DNS 服务器的地址,你去问它应该能问到”。
- 本地 DNS 于是转向问权威 DNS 服务器:“老三,www.server.com对应的IP是啥呀?” server.com 的权威 DNS 服务器,它是域名解析结果的原出处。为啥叫权威呢?就是我的域名我做主。
- 权威 DNS 服务器查询后将对应的 IP 地址 X.X.X.X 告诉本地 DNS。
- 本地 DNS 再将 IP 地址返回客户端,客户端和目标建立连接。
DHCP
在生活中,有着大量的移动设备,这些移动设备大多并不具有一个固定的IP,而是采用DHCP技术动态的租用IP,省去了繁琐的配置IP地址的步骤。DHCP协议主要分为下面四个步骤:
客户端首先发起 DHCP 发现报文(DHCP DISCOVER) 的 IP 数据报,由于客户端没有 IP 地址,也不知道 DHCP 服务器的地址,所以使用的是 UDP 广播通信,其使用的广播目的地址是 255.255.255.255(端口 67) 并且使用 0.0.0.0(端口 68) 作为源 IP 地址。DHCP 客户端将该 IP 数据报传递给链路层,链路层然后将广播到所有的网络中设备。
注意: 电脑的操作系统安装了TCP/IP协议栈,这个协议栈其中包含了DHCP客户端进程,这个客户端会广播发送一个发现服务器的报文,格式为UDP封装,目的端口号为68,源端口号为67。
DHCP 服务器收到 DHCP 发现报文时,用 DHCP 提供报文(DHCP OFFER) 向客户端做出响应。该报文仍然使用 IP 广播地址 255.255.255.255,该报文信息携带服务器提供可租约的 IP 地址、子网掩码、默认网关、DNS 服务器以及 IP 地址租用期。
- 客户端收到一个或多个服务器的 DHCP 提供报文后,从中选择一个服务器,并向选中的服务器发送 DHCP 请求报文(DHCP REQUEST进行响应,回显配置的参数。
- 最后,服务端用 DHCP ACK 报文对 DHCP 请求报文进行响应,应答所要求的参数。

一旦客户端收到 DHCP ACK 后,交互便完成了,并且客户端能够在租用期内使用 DHCP 服务器分配的 IP 地址。如果租约的 DHCP IP 地址快期后,客户端会向服务器发送 DHCP 请求报文:
- 服务器如果同意继续租用,则用 DHCP ACK 报文进行应答,客户端就会延长租期。
- 服务器如果不同意继续租用,则用 DHCP NACK 报文,客户端就要停止使用租约的 IP 地址。
但是,广播一般是无法突破局域网的路由器的,但是不可能每个局域网都配置一个DHCP服务器,因此就出现了DHCP中继代理:
- DHCP 客户端会向 DHCP 中继代理发送 DHCP 请求包,而 DHCP 中继代理在收到这个广播包以后,再以单播的形式发给 DHCP 服务器。
- 服务器端收到该包以后再向 DHCP 中继代理返回应答,并由 DHCP 中继代理将此包广播给 DHCP 客户端 。

说明: 关于IP地址为0.0.0.0和255.255.255.255的含义,可以看一下下面的文章: https://www.zhihu.com/question/267097519
广播地址255.255.255.255虽然是广播所有互联网的所有主机,但是一般情况是走不出局域网的。会被路由器拦截,所以才需要DHCP中继代理。
NAT
IPv4的数量是非常有限的,随着互联网的高速发展,IPv4的资源已经非常紧缺了,于是IPv4的设计者们提出了一种网络地址转换技术来缓解IPv4被消耗完的风险,即NAT技术。简单的来说 NAT 就是同个公司、家庭、教室内的主机对外部通信时,把私有 IP 地址转换成同一个公有 IP 地址。由于传输协议TCP、UDP必须使用到端口,而NAT正是借助这个端口来实现的。
可以看到,NAT技术的玄机就在于NAT路由器的转换表里面,私有IP都转换成了同一个公网IP,而这公网IP如何找到对应的私网IP就是通过端口号一一映射的。图中有两个客户端 192.168.1.10 和 192.168.1.11 同时与服务器 183.232.231.172 进行通信,并且这两个客户端的本地端口都是 1025。此时,两个私有 IP 地址都转换为公有地址 120.229.175.121,但是以不同的端口号作为区分。于是,生成一个 NAPT 路由器的转换表,就可以正确地转换地址跟端口的组合,令客户端 A、B 能同时与服务器之间进行通信,且这种转换表在 NAT 路由器上自动生成。在 TCP 的协议下,建立 TCP 连接首次握手时的 SYN 包一经发出,就会生成这个表,而后又随着收到关闭连接时发出 FIN 包的确认应答从表中被删除。
当然,这种NAT技术也有一些缺点:
- 外部无法主动与 NAT 内部服务器建立连接,因为 NAPT 转换表没有转换记录
- 转换表的生成与转换操作都会产生性能开销
- 通信过程中,如果 NAT 路由器重启了,所有的 TCP 连接都将被重置
注意: NAT技术是用来缓解IPv4地址不足的压力的,如果有足够的IP地址,就完全不需要整这个花里胡哨的东西,比如采用足够IP地址的IPv6。
ARP与RARP
先简单了解一下数据链路层的MAC地址,数据链路层传输数据必须得到MAC地址:
在传输一个 IP 数据报的时候,确定了源 IP 地址和目标 IP 地址后,就会通过主机的路由表确定 IP 数据包下一跳。然而,网络层的下一层是数据链路层,所以还要知道下一跳的 MAC 地址。由于主机的路由表中可以找到下一跳的 IP 地址,所以可以通过 ARP 协议求得下一跳的 MAC 地址。
- 主机会通过广播发送 ARP 请求,这个请求包中包含了想要知道的 MAC 地址的主机 IP 地址
- 当同个链路中的所有设备收到 ARP 请求时,会去拆开 ARP 请求包里的内容,如果 ARP 请求包中的目标 IP 地址与自己的 IP 地址一致,那么这个设备就将自己的 MAC 地址放入 ARP 响应包返回给主机
总的来看,ARP就是已知路由器的IP地址,并根据这个IP地址寻址路由器的MAC地址
注意: 主机通常会把第一次通过 ARP 获取的 MAC 地址缓存起来,以便下次直接从缓存中找到对应 IP 地址的 MAC 地址。但是MAC 地址的缓存是有一定期限的,超过这个期限,缓存的内容将被清除。
当然,既然有ARP技术已知IP地址求MAC地址,那么反过来也自然有已知MAC地址求IP地址的服务,他就是RARP服务。通常这需要架设一台 RARP 服务器,在这个服务器上注册设备的 MAC 地址及其 IP 地址,然后再将这个设备接入到网络,接着:
- 该设备会发送一条「我的 MAC 地址是XXXX,请告诉我,我的IP地址应该是什么」的请求信息。
- RARP 服务器接到这个消息后返回「MAC地址为 XXXX 的设备,IP地址为 XXXX」的信息给这个设备。
最后,设备就根据从 RARP 服务器所收到的应答信息设置自己的 IP 地址。
ICMP
ICMP 全称是 Internet Control Message Protocol,也就是互联网控制报文协议。ICMP 主要的功能是:确认 IP 包是否成功送达目标地址、报告发送过程中 IP 包被废弃的原因和改善网络设置。在 IP 通信中如果某个 IP 包因为某种原因未能达到目标地址,那么这个具体的原因将由 ICMP 负责通知。
如上图:主机 A 向主机 B 发送了数据包,由于B已关机,途中的路由器 2 未能发现主机 B 的存在,这时,路由器 2 就会向主机 A 发送一个 ICMP 目标不可达数据包,说明发往主机 B的包未能成功。
CMP 大致可以分为两大类:
- 一类是用于诊断的查询消息,也就是查询报文类型
- 另一类是通知出错原因的错误消息,也就是差错报文类型

而ICMP报文和TCP报文一样,也是封装在IP报文里面的,如下图所示:
对于差错报文类型,主要有以下几类情况:
- 目标不可达消息
- 原点抑制消息
- 重定向消息
- 超时消息
目标不可达:
IP 路由器无法将 IP 数据包发送给目标地址时,会给发送端主机返回一个目标不可达的 ICMP 消息,并在这个消息中显示不可达的具体原因,原因记录在 ICMP 包头的代码字段。
原点抑制:
在使用低速广域线路的情况下,连接 WAN 的路由器可能会遇到网络拥堵的问题。ICMP 原点抑制消息的目的就是为了缓和这种拥堵情况。当路由器向低速线路发送数据时,其发送队列的缓存变为零而无法发送出去时,可以向 IP 包的源地址发送一个 ICMP 原点抑制消息。收到这个消息的主机借此了解在整个线路的某一处发生了拥堵的情况,从而增大 IP 包的传输间隔,减少网络拥堵的情况。然而,由于这种 ICMP 可能会引起不公平的网络通信,一般不被使用。
重定向:
如果路由器发现发送端主机使用了不是最优的路径发送数据,那么它会返回一个 ICMP 重定向消息给这个主机。在这个消息中包含了最合适的路由信息和源数据。这主要发生在路由器持有更好的路由信息的情况下。路由器会通过这样的 ICMP 消息告知发送端,让它下次发给另外一个路由器。
超时:
IP 包中有一个字段叫做 TTL (生存周期),它的值随着每经过一次路由器就会减 1,直到减到 0 时该 IP 包会被丢弃。此时,路由器将会发送一个 ICMP 超时消息给发送端主机,并通知该包已被丢弃。设置 IP 包生存周期的主要目的是为了在路由控制遇到问题发生循环状况时,避免 IP 包无休止地在网络上被转发。
