目录
TCP/IP 分层体系结构
计算机网络是一个非常庞大且复杂的系统,所以在设计之初就严格遵守着「分层」的设计理念。分层思想将庞大的问题细分为了若干个局部的小问题,具有分层隔离、易于实现和维护、以及能促进标准化工作的优势。其中「标准化」是促进互联网全球化的关键,各种各样的网络协议,就是标准化的结果。
目前,计算机网络的分层体系结构主要有 2 个:
- 偏学术研究的 OSI(Open Systems Interconnection Reference Model,开放系统互联基本参考模型)七层模型;
- 偏实际应用的 TCP/IP(Transmission Control Protocol/Internet Protocol,传输控制协议/因特网协议)五层模型。
我们主要讨论主流的 TCP/IP 五层模型。
- L1(物理层):最底层的数据传输物理媒介。主要提供各种物理连接设备,如:网卡、串口卡、网线、光模块等等。
- L2(数据链路层):主要提供对物理层进行访问的各种接口卡的驱动程序,如:网卡驱动程序等。数据链路层通过 MAC 地址来定位本地子网中的主机。
- L3(网路层):负责将网络数据包传输到目的位置,通过 IP 地址来定位不同子网间的主机。
- L4(传输层):为应用程序之间提供端到端连接,通过 Port 来定位到主机上的应用程序。
- L5-7(应用层):顾名思义,主要由应用程序提供服务,是用来对传输数据进行语义解释的 “人机交互界面层”。
分层 PDU(Protocol Data Unit,协议数据单元)类型
- 物理层:比特(Bit);
- 数据链路层:数据帧(Frame);
- 网络层:数据包(Packet);
- 传输层:
- TCP 数据段(Segment)
- UDP 数据报(Datagram)
- 应用层:消息/数据(Message/Data)
分层 PDU 的封装与解封装
逐层封装
逐层解封装
PDU 的传输方式
-
单播(Unicast):在发送者和接收者之间实现点对点网络连接。如果发送者同时给多个的接收者传输相同的数据,也必须相应的复制多份相同的数据包。如果有大量接受者希望获得数据包的同一份拷贝时,将导致发送者负担沉重、延迟长、网络拥塞;
-
组播(Multicast):在发送者和收者之间实现一点对多点的网络连接。如果发送者同时给多个接收者传输相同的数据,也只需复制一份相同的数据包。它提高了数据传送效率,减少了骨干网络出现拥塞的可能性。组播解决了单播和广播效率低的问题。当网络中的某些用户需求特定信息时,组播源(即组播信息发送者)仅发送一次信息,组播路由器借助组播路由协议为组播数据包建立树型路由,被传递的信息在尽可能远的分叉路口才开始复制和分发。
-
多播(Multicast):1988 年 Steve Deering 首次在其博士论文中提出多播的概念。多播是 IPv6 数据包的 3 种基本目的地址类型之一,多播是一点对多点的通信,IPv6 没有采用 IPv4 中的组播术语,而是将广播看成是多播的一个特殊例子。
-
广播(Broadcasting):是指在 LAN 内广播数据包,所有在 LAN 内的主机都将收到这些数据包。广播意味着向 LAN 内每台主机都投递一份数据包,不论这些主机是否愿意接收该数据包。所以广播的使用范围非常小,只在本地子网内有效,通过路由器和网络设备控制广播传输。
-
泛洪:将某个端口收到的数据从除该端口之外的所有端口发送出去。泛洪操作广播的是普通数据帧而不是广播帧。
PDU 的安全校验
以太网的 CRC32 比较强,但它只能保证同一个网段上的通信不会出错(两台机器的网线插到同一个交换机上,这时候以太网的 CRC 是有用的)。
但是,如果两台机器之间经过了多级路由器呢?
我知道同一个以太网域内,Ethernet 的 FCS 尾部有 CRC32 字段会保证数据完整性,但是作者说在多级路由器之间传输的数据无法保证数据完整性。原因是什么呢,是不是因为 “由于多级路由器之间的传输不是使用的 Ethernet 协议栈,所以就没有 CRC32 等算法?”
那么问题来了,为什么路由器间的传输不做完整性校验呢?如果整个链路的每个传输环节都有类似于 CRC 这样的校验算法,那么是不是上层是不是就可以省略数据校验了?为什么实际情况下没有这样做呢?是成本因素考量?
还有一个问题就是,既然 MAC 帧已经有 CRC32 校验了,为什么位于运输层的 UDP 数据包仍然有 checksum 字段?
这个世界没有 100% 的可靠!即使电脑也会犯错,数据受到干扰更会犯错,甚至还有恶意的人为修改数据。那么互联网的专家们是如何最大限度保证数据的完整性的呢?
链路层强校验
通常数据离开电脑在各种介质中流淌的场合是最容易出错的,因为信号会有各种干扰。介质包括网线、光纤、空气,由于出错概率颇大,故数据链路层的数据完整性校验采用强校验,CRC 校验。
所谓强校验,是指一旦数据发生了错误,CRC 校验会高可靠性地检测倒错误并丢弃,可靠性可以达到 1-1/108。
以太网为例,一帧的数据大约 1500 字节,而 CRC 却要为这 1500 字节提供完整性,而 CRC 的取值空间去仅仅 4 个字节!对,你没有看错,仅仅 4 个字节,却要为 1500 字节服务。客人远远超出服务员的人数,能够达到高可靠性已经难能可贵了。
网络层弱校验
意味着数据链路层提交给 IP 层的数据,有可能是错误的。提交的过程是一次数据的复制过程,这里可能会引入错误,上文已经提到了这一点。浓眉大眼、五官端正的电脑竟然也会犯错,这实在是没有想到啊!
没有关系,IP 层不是还有 Checksum 校验吗?
有同学会说,CRC 是非线性的、高级校验算法,而 Checksum 不过是线性的、低级的校验和算法,CRC 没有校验出的,你 Checksum 能校验出吗?
尺有所长,寸有所短,真不好说 Checksum 是否能校验出 CRC 的疏漏。但是如果我告诉你,IP 层的 Checksum 主要目的是为了防止数据在电脑中的复制操作产生 IP 头数据错误错误,你可能就不会那么纠结了。因为 IP 校验压根不覆盖数据部分。
这里的核心思想是,距离数据的发源地越近的地方,将错误的数据丢弃,避免错误的数据奔袭万里贻害网络资源,善莫大焉!
传输层弱校验
不怕不怕,不是还有 TCP/UDP 的校验吗?
问题是 TCP/UDP 也是 Checksum 弱校验,既然是弱校验,意味着可靠性堪忧,尽然堪忧为何不采用强校验,例如 CRC 或 MD5 或 SHA 校验呢?
在设计 TCP/IP 时代,电脑的计算能力没有那么强大,CRC 耗费的 CPU 资源大,会让电脑一下子慢下来,而 Checksum 只是一个单纯的加法,耗费的 CPU 资源小,故 Checksum 胜出!
不怕不怕不怕啦,我们还有安全层的校验!
安全层超强校验
这里的安全层指的是业界妇孺皆知的 TLS,通常 TLS 的校验值空间具有 16 或 20 字节,取决于是 MD5 还是 SHA1。如果觉得可靠性不够,可以采用 SHA 512, 校验空间可以达到 64 字节。
此外,安全层在计算这些校验值时,还会加入密钥,只有发送方、接收方知晓,任何第三方都无法伪造。这样就真正实现了超过可靠性的数据完整性!
应用层超强校验
数据是通信的核心要素,如果数据错了,一切都是浪费感情!
所以,应用层做为最后一道管卡,要尽可能采用超强校验,来最大限度地保护数据的完整性!
内核协议栈分层架构概览
-
驱动程序层(Physical device hardware):提供连接硬件设备的各种软件接口。
-
设备接口层(Device agnostic interface):提供驱动程序的各种抽象接口。作为驱动层和协议层之间的中间层,提供无关具体设备的统一接口定义。
-
网络协议层(Network protocols):提供 L3-4 TCP/IP 网络协议的具体实现。例如:ARP、IP、ICMP、TCP 等。
-
协议接口层(Protocol agnostic interface):也称为 BSD Socket API 层,本质是 SCI(系统调用接口)的一部分,向上层应用程序提供各种网络编程接口。作为协议层和应用层之间的中间层,提供无关具体协议的统一 Socket 接口定义。