一、局域网与广域网
如果按照地理区域划分,我们可以把网络划分为局域网和广域网:
广域网 WAN:是跨越广阔地理区域(城市、国家、全球)的大型计算机网络,它连接了多个局域网。

注意:所谓的'局域网'和'广域网'只是一个相对的概念。比如我们国家的广域网对于世界来说可以看做一个比较大的局域网。
局域网 LAN:是在一个有限的地理范围内(例如一栋楼、一个校园、一个家庭)将计算机、服务器和其他设备连接起来的网络。

二、初识协议
我们向另一台设备发送消息时,发送的不仅仅只有消息(这里的消息在网络中称为报文),还有报头,而这个报头就是协议。
- 所谓'协议'就是一种约定,通信双方只要遵守曾经一起制定的约定,就可以使用这种约定来完成某些事情。
- 而网络协议就是通信计算机双方必须共同遵从的一组约定,因此我们一定要将这种约定用计算机语言表达出来,此时双方计算机才能识别约定的相关内容。
生活示例:打电话约定电话铃响的次数
张三和李四曾经一起约定:以后我们打电话先不要接,如果电话只响一声,说明我喊你吃饭。如果响两声,说明我喊你写作业……
如此,只要双方遵守约定,就可以间接达成通信目的了。
计算机世界的示例:错误码
通信计算机双方曾经做过如下约定:
- 如果 code 为 0,表示数据可靠
- 如果 code 为 1,表示数据不可靠,且对应错误原因 1
- 如果 code 为 2,表示数据不可靠,且对应错误原因 2
- ……
struct cmd {
int code : 0;
int data : 66;
};
这是一个位段结构,我们是可以通过位段/结构体来表示某种协议规定的。在计算机网络中,协议其实就是通过类似结构体/位段这样的数据结构来实现的。
网络协议由谁来定?
完善的协议,需要更多更细致的规定,并让参与的人都要遵守。
计算机生产厂商有很多,计算机操作系统也有很多,计算机网络硬件设备还是有很多。
如何让这些不同厂商之间生产的计算机能够相互顺畅的通信?就需要有人站出来,约定一个共同的标准,大家都来遵守,这就是网络协议。
一般具有定制协议或者标准的资格的组织或者公司都必须是业界公认或者具有江湖地位的组织或者公司。
报文在网络运输中以什么形式存在?
以二进制的光电信号的形式存在,以光电信号的频率、强弱来表示 0/1。
1. 协议分层
网络协议栈是被设计成为层状结构的,其目的就是为了将层与层之间进行解耦,保证代码的可维护性和可扩展性。
为什么协议要分层?
协议的本质也是软件,在软件工程这个学科中有个重要的概念:软件分层。
日常编程中常见软件分层的体现:
- 结构体、类的继承、多态现象。
- 代码逻辑上的分离:回调函数实现。
软件分层最大的好处就是:高内聚低耦合,保证易维护。
感性理解:降低了层与层之间的耦合度,如果某一层出错,问题影响的范围只有这一层,极大降低损失,而且查问题也只需查这一层的范围,极大缩小维护的时间成本。
其他网络协议分层的原因:
- 技术上:网络的规模太大,不分层维护很困难。
- 事实上:网络的问题本来就是分层的。
举个打电话的例子,直观的感受协议分层带来的好处
打电话的时候,站在技术人员的角度实际这两个人并不是直接进行沟通的,而是甲的电话将甲说的话记录下来,经过一系列编码转码后,通过通信网络将信息从甲的电话传递到了乙的电话,然后信息在乙的电话中再经过对应的编码转码,最后乙才通过话筒听到了甲所说的话。
其中,人与人之间通信使用的是汉语,我们可以将其称为语言层;而电话和电话之间通信使用的是电话系统相关的一些接口,我们可以将其称之为通信设备层。

如果将语言层换成英语,双方仍然可以正常沟通。

- 分层最大的好处在于'封装',在分层情况下,将某层的协议进行替换后,通信双方之间是不会受到影响的。
- 通过上面的简单例子,我们能理解,分层可以实现解耦合,让软件维护的成本更低。
- 我们还可以看出,虽然在打电话时我们并不是直接进行沟通的,但是我们可以认为我们是在直接进行沟通。尽管其底层实际上是非常复杂的行为。
对于网络协议我们需要有一个基本的认识:关于通信,同层协议可以认为自己在和对方层直接进行通信,从而达到简化对于网络协议栈的理解。

2. OSI 七层模型
OSI(Open System Interconnection,开放系统互连)七层网络模型称为开放式系统互联参考模型,是一个逻辑上的定义和规范。
- OSI 把网络从逻辑上分为了七层,每一层都有相关的、相对应的物理设备,比如路由器,交换机。
- OSI 七层模型是一种框架性的设计方法,其最主要的功能就是帮助不同类型的主机实现数据传输,比如手机和电视之间数据的传输。
- OSI 七层模型最大的优点是将服务、接口和协议这三个概念明确地区分开来,概念清楚,理论也比较完整,通过七个层次化的结构模型使不同的系统不同的网络之间实现可靠的通讯。


其实在网络角度,OSI 定的协议 7 层模型其实非常完善,但是在实际操作的过程中,会话层、表示层是不可能接入到操作系统中的,所以在工程实践中,最终落地的是 5 层协议。
要理解 OSI,需要我们学习完网络才可以理解,这里知道就可以。所以我们按照 TCP/IP 四层模型为主学习。
3. TCP/IP 五层(或四层)模型
TCP/IP 是一组协议的代名词,它还包括许多协议,组成了 TCP/IP 协议簇。
TCP/IP 通讯协议采用了 5 层的层级结构,每一层都呼叫它的下一层所提供的网络来完成自己的需求。
- 物理层:负责光电信号的传递。比如现在以太网通用的网线(双绞线)、早期以太网采用的同轴电缆(现在主要用于有线电视)、光纤、无线 wifi 使用的电磁波等都属于物理层的概念。物理层的能力决定了最大传输速率、传输距离、抗干扰性等。
- 集线器(Hub)工作在物理层:光电信号随着传输距离的增大,会越来越弱,直至消失,而集线器可以将光电信号复原增强,从而完成超长距离传输。
- 数据链路层:负责设备之间的数据帧的传送和识别。例如网卡设备的驱动、帧同步(就是说网线上检测到什么信号算作新帧的开始)、冲突检测(如果检测到冲突就自动重发)、数据差校验等工作。
- 有以太网、令牌环网、无线 LAN 等标准
- 交换机(Switch)工作在数据链路层:主要作用是在数据链路层智能地转发数据帧,实现高效、安全的本地设备间通信(避免数据碰撞)。
- 网络层:负责地址管理和路由选择。例如在 IP 协议中,通过 IP 地址来表示一台主机,并通过路由表的方式规划出两台主机自己在那的数据传输线路(路由)。
- 路由器(Router)工作在网络层。
- 传输层:负责两台主机之间的数据传输。如传输控制协议(TCP),能够确保数据可靠的从源主机发送到目标主机。
- 应用层:负责应用程序间沟通。如简单电子邮件传输(SMTP)、文件传输协议(FTP)、网络远程访问协议(Telnet)等。
- 网络编程主要就是针对应用层。
与 OSI 七层模型各层的对应关系:

可以看到,区别在于将应用层、表示层、会话层压缩为了一层,统称应用层。
- 操作系统对应的传输层和网络层,这两层的 TCP 和 IP 协议是网络的核心,故此命名。
- 驱动程序对应数据链路层
- 底层硬件对应物理层
- 应用层则对应用户层
具体如图所示:

一般而言:
- 对于一台主机,他的操作系统内核实现了从传输层到物理层的内容。
- 对于一台路由器,它实现了从网络层到物理层。
- 对于一台交换机,它实现了从数据链路层到物理层。
- 对于集线器,它只实现了物理层。
注意:这并不绝对,只是一般而言。很多交换机也实现了网络层的转发; 很多路由器也实现了部分传输层的内容 (比如端口转发);
物理层我们考虑的比较少,我们只考虑软件相关的内容。因此很多时候我们直接称为 TCP/IP 四层模型。
三、网络协议栈与 OS 的关系
上文提到:网络层与传输层的工作都是由 OS 来完成的。这就意味着网络和 OS 必然是强关联的。

究竟什么是协议?
下面,仔细看看下面的图:

问题:主机 B 能识别 data,并且准确提取 a=10,b=20,c=30 吗? 答案是肯定的!因为双方都有同样的结构体类型 struct protocol。也就是说,用同样的代码实现协议,用同样的自定义数据类型,天然就具有'共识',能够识别对方发来的数据,这不就是约定么?约定就是协议!
关于协议的朴素理解:所谓协议,就是通信双方都认识的结构化的数据类型
因为协议是分层的,所以每层双方都有协议。同层之间互相可以认识对方的协议。
四、网络通信的基本流程
1. 网络通信的本质:就是贯穿协议栈的过程
用户 A 向用户 B 发送消息的通信过程是这样的:用户 A 发送的数据由应用层向下贯穿协议栈到物理层的网卡,再在用户 B 的网卡由物理层向上贯穿协议栈到用户 B 的应用层。

而其中每层都有协议,所以当我进行上述传输流程的时候,要进行封装和解包

下面我们来补充一下概念:

- 报头部分:就是对应协议层的结构体字段,称作报头。
- 除了报头,剩下的部分为有效载荷。
- 报文 = 报头 + 有效载荷
然后,我们在明确一下不同层的完整报文的叫法:
- 不同的协议层对数据包的的称谓不同:
- 传输层叫做段(segment)
- 网络层叫做数据报(datagram)
- 数据链路层叫做帧(frame)
- 应用层数据通过协议栈发到网络上时,每层协议都要加上一个数据首部(属于该层协议的报头)(header),称为封装。
- 首部信息中包含了一些类似于首部有多长,载荷 (payload) 有多长,上层协议是什么等信息。
- 数据封装成帧后发到传输介质上,到达目的主机后每层协议再剥掉相应的首部(解包的过程),根据首部中的'上层协议字段'将数据交给对应的上层协议处理(分用的过程)。
- 在每层中,有效载荷是不同的,而是相对的。比如传输层封装报头后将报文交给网络层,在网络层看来,这整条报文都是有效载荷,自己封装的报头才是报头。
总结一下: 在网络传输的过程中,数据不是直接发送给对方主机的,而是先要自定向下将数据交付给下层协议,最后由底层发送,然后由对方主机的底层来进行接受,在自底向上进行向上交付。 示意图:

2. 数据包的封装与分用
每层协议都要加上一个数据首部(属于该层协议的报头)(header),称为封装。
下图为数据封装的过程:

根据首部中的'上层协议字段'将数据交给对应的上层协议处理就是分用的过程。
下图为数据分用的过程:

可以看到,这是个树形结构。
封装和解包是大部分协议的共性,未来我们学习具体协议时都会面临这两个问题:
- 几乎任何层的协议,都要提供一种能力,将报头和有效载荷分离的能力——解包。
- 几乎任何层的协议,都要提供一种能力,决定将自己的有效载荷交付给上层的哪一个协议的能力——分用。
想清楚这些,我们面对封装和解包才不会困惑。
3. 同局域网的两台主机通信
在局域网内,两台主机是可以直接通信的。
3.1 认识 MAC 地址
每台主机在局域网上,要有唯一的标识来保证主机的唯一性:mac 地址。
- MAC 地址用来识别数据链路层中相连的节点。
- 长度为 48 位,即 6 字节,一般用 16 进制数字 + 冒号来表示(如 08::00:27:03:fb:19)
- mac 地址在网卡出厂的时就确定了,不可修改
- mac 地址通常是唯一的(虚拟机中的 mac 地址不是真实的 mac 地址,所以可能会冲突;也有一些网卡支持用户配置 mac 地址)。
3.2 原理
讲一个小故事: 老师老师在课堂上讲课,大家都在认认真真听课,而张三在打瞌睡,于是老师大喊一声:'张三,你给我站起来!',于是张三听到后就立马站起来了,这个消息是广播形式的,所有人都收得到,但只有张三会做出应答。
对应计算机世界中: 教室里的每一个人都是一个设备,每个人的名字就是一个 mac 地址,老师的广播式发送消息就是局域网的主机通信,也就是说局域网中的每一个主机都会收到报文,但会根据报头(包含源 mac 地址和目的 mac 地址)中的目的 mac 地址来判断这个报文是不是发给自己的,不是的话就丢弃。

总结:局域网内传输数据时,该局域网内的所有主机都收得到,只不过经过筛选后只提交上来发给自己的数据。
3.3 碰撞
当主机 A 在向主机 B 发送数据时,其他主机彼此之间可能也在通信,甚至于主机 A 和主机 B 同时还在与其他主机通信。
而在同一个局域网中的所有主机都是共用一个信道的,也就是说,对于所有主机,信道是共享资源,是资源就是有限的,有限的就会产生竞争。
- 以太网中,任何时刻,只允许一台主机向网络中发送数据。
- 如果有多台同时发生,会产生数据干扰,称为碰撞。
- 为了避免碰撞,所有主机发送数据时会进行碰撞检测和碰撞避免。
- 没有交换机的情况下,一个以太网就是一个碰撞域。
- 交换机的作用就是划分碰撞域的,比如说主机 B 在主机 A 的左边,那么主机 A 给主机 B 发送的数据就没必要向右边传了,此时交换机就可以拦截,让右边的碰撞域减少垃圾数据。
4. 跨局域网的两台主机通信
局域网之间都是通过路由器连接的,所以一个路由器至少可以横跨两个局域网。而这些被路由器级联的局域网都认为,该路由器是本局域网的一台主机,因此路由器可以和这些局域网内的任意一台主机进行通信。
比如局域网 1 当中的主机 A 想要和局域网 2 当中的主机 H 进行通信,那么主机 A 可以先将数据发送给路由器,然后路由器再将数据转发给局域网 2 当中的主机 H。

重要的是:路由器支持不同通信标准的两个局域网间的通信。
比如局域网 1 是以太网,而局域网 2 是令牌环网,由于它们是不同的通信标准,它们给报文添加的报文是不同的,所以令牌环网当中的主机无法对以太网当中的数据帧进行解包。

这种情况实际是由路由器来处理的,路由器是工作在网络层的一个设备,我们可以认为路由器当中的协议栈是下面这样的:

当数据要从局域网 1 发送到局域网 2 时,路由器收到局域网 1 的数据后,会将以太网封装的报头进行解包,然后将剩下的部分向上交付给网络层,在网络层进行一系列数据分析后,再将数据向下交付给链路层,此时链路层就会给该数据封装令牌环的报头信息,再将数据发送到局域网 2 中,实现了网络通信标准的转换。

那路由器怎么知道要发给哪个局域网呢?
4.1 认识 IP 地址
路由器其实是通过 IP 地址来确定数据的转发方向的,因特网上的每台主机都有一个唯一的 IP 地址,网络层在数据向下进行封装时,封装的报头包含两个字段:源 IP 地址和目的 IP 地址。
当路由器需要将一个局域网的数据转发到另一个局域网时,当数据向上交付到路由器的网络层时,路由器就可以获取发生方封装的 IP 地址信息,然后根据这个 IP 地址在路由表中查找,就可以确定这个数据应该发送给哪个局域网。
示意图如下:

需注意的是:路由器也是一台主机,也具有对数据包封装、解包和分用的能力。
知道 IP 地址的作用后,我们来介绍一下 IP 地址。
IP 协议有两个版本,IPv4 和 IPv6,我们以 IPv4 为主。
- IP 地址是在 IP 协议中,用来标识网络中不同主机的地址
- 对于 IPv4 来说,IP 地址是一个 4 字节,32 位的整数
- 我们通常也使用'点分十进制'的字符串表示 IP 地址,例如 192.168.0.1 ; 用点分割的每一个数字表示一个字节,范围是 0 - 255;
4.2 IP 地址和 Mac 地址的区别
- IP 地址在整个路由过程中,一直不变 (目前,我们只能这样说明,后面再修正)
- Mac 地址一直在变
- 目的 IP 是一种长远目标,Mac 是下一阶段目标,目的 IP 是路径选择的重要依据,而 mac 地址是局域网转发的重要依据。
举个现实生活中的例子: 你在广西,而你想要去上海,你选择一路骑行过去,而你必须要经历这样的一个过程:为了选择一个最短路径,在广西得问问老表:'我要去上海,我该怎么走啊?',老表说:'你得先去湖南。',到了湖南后,你得问问湖南老表:'我想去上海,我该怎么走?',湖南老表说:'那你得先去江西哦!'到了江西后,你得问问江西老表:'我想去上海,我该怎么走?'江西老表说:'那你得先去浙江哦!'……于是你就顺利到达了上海。
这里每个省份就是一个局域网,你就是需要发送的数据,而指路人就是路由器,我们的目的地上海就是目的 IP 地址,出发地广西就是源 IP 地址,mac 地址就是我们的一路途径的各个省份。
不难看出:
- IP 地址是指导我们进行路径规划的,一般是不变化的。从哪来?到哪去?是一直不变的。
- Mac 是指导我们下一站该去哪里,会一直变化,变化的依据就是 IP 地址。出局域网后,源 mac 地址和目的 mac 地址都要丢弃,让路由器重新封装。
总结 IP 网络的意义和网络通信的宏观流程:

IP 网络层存在的意义:提供网络虚拟层,让世界的所有网络都是 IP 网络,屏蔽最底层网络的差异。


