TCP/IP 网络模型(网络协议栈)
TCP/IP 网络模型(网络协议栈)
TCP/IP协议栈是计算机网络通信的基础,它将复杂的网络通信过程分解为四个层次,使得上层应用可以透明地使用网络服务。本文将详细介绍TCP/IP四层模型的结构、功能以及数据封装和解包的过程,帮助读者理解计算机网络通信的基本原理。
我们几乎每天都会频繁地使用网络,观看视频、使用微信、浏览网页等等,然而,计算机彼此之间究竟是怎样建立连接的,这些数据又是如何在错综复杂的网络中进行传输的呢?
而这恰恰就是网络协议的神奇之处:它将所有繁复的底层通信逻辑都隐藏了起来,使得上层的使用者感觉一切都极为透明,就好像它根本不存在一样。
学习计算机网络有个最大的感受就是,既可以“自顶向下”逐层拆解网络协议,也可以“自底向上”逐步构建网络协议。
分层
为什么计算机网络有如此神奇之处?
因为计算机网络分层做得太棒了!
剑桥大学计算机科学教授 David Wheeler 说的一句编程领域非常经典的话:
“All problems in computer science can be solved by another level of indirection”
即:
计算机科学领域的任何问题都可以通过增加一个间接的中间层得以解决。
OSI 七层网络模型
相信大家一定经常听说 七层负载均衡、四层负载均衡,以及三层路由器、三层交换机这些名字。
实际上这里这里所说的七层、三层、四层指的就是 OSI 网络模型。
所谓四层就是基于 IP + 端口的负载均衡,七层就是基于 URL 等应用层信息的负载均衡,同样的还有基于二层 MAC 地址,三层 IP 地址的负载均衡
而 OSI(Open System Interconnection,开放式通信互联) 是由 ISO(International Organization for Standardization,国际标准化组织) 制定的标准模型。
目的在于制定一种将世界各地的各种计算机互联的标准:
这张图就更加形象具体了,每一层都有对应的网络设备:
从上到下分别是:
- 应用层,就是指特定的应用层协议,比如 HTTP、远程文件协议 FTP、邮件协议POP3、远程登录协议 SSH 等
- 表示层,负责数据处理转换:包含数据格式、编码解码、加密解密等
- 会话层,负责建立和维护不同主机之间的通信连接
- 传输层,主机进程之间的数据传输服务,注意,这里的进程间实际就是指传输层需要端口号来识别进程
- 网络层, 主机端到端的路由和寻址(这一层寻址是依靠 IP 地址,决定数据在网络的路径)
- 数据链路层,负责管理相邻节点之间的数据通信:包括 数据封装成帧、MAC 寻址、流量控制、差错控制
- 物理层,数据通信的光电物理特性、时钟同步、传输比特流等
正是因为 OSI 模型过于庞大、复杂,且部分层的功能重复、划分不清,导致最终并未成为广泛使用的标准模型,反倒是 TCP/IP 四层网络模型成为了事实上的标准网络模型。
TCP/IP 四层模型
TCP/IP 协议栈是一个包含多种网络通信协议的集合,主要包括两个核心协议:TCP(传输控制协议)和 IP(网际协议)。
由于 TCP 和 IP 协议是最核心的两个协议,也是 TCP/IP 最早通过的两个标准协议,因此采用被称为 TCP/IP 协议栈。
TCP/IP 将软件通信过程抽象为四个层次,形成了协议堆栈,每个层次实现不同的通信协议,根据功能的不同,这些协议被分配到这四个层次中,通常被视为简化的七层 OSI 模型。
一个典型的 TCP/IP 四层模型如下图:
虽然 TCP/IP 协议和 OSI 模型并不能完全对应,但我们可以在 OSI 模型中找到 TCP/IP 的大致位置。
从上图可以看出,OSI 模型的最上面三层(应用层、表示层和会话层)在 TCP/IP 中归为一个应用层;而数据链路层和物理层被归类为网络接口层(Network Interface)。
虽然 TCP/IP 协议栈是事实的标准,但是正如前面提到的七层负载、四层负载,还是以 OSI 模型来描述。
网络协议封装和解包
数据包发送流程
上图显示了一个数据包经由发送方、网络交换机、路由器,最终抵达接收方的过程。
可以看出,在进行网络传输时,数据包会按照 TCP/IP 协议栈,对上一层发来的数据进行逐层处理;然后加上该层的协议头,再发送给下一层。
这个过程就叫做封装(encapsulation)
数据会在交换机和路由器的协议栈上上下下,然后向上到达接收方主机的协议栈。
我们常说的三层路由器、二层交换机,指的就是他们各自能识别到哪一层的协议,工作在这一层,即根据协议头的IP、端口、MAC地址等进行相应的转发、广播。
值得一提的是,主机实现了 TCP/IP 协议栈所有层,这与因特网体系结构将它的复杂性放在网络边缘实现是一致的。
TCP/IP 数据包封装示意图:
以一个 HTTP 请求为例(省略很多细节),发送端自上而下分别会进行:
- 应用层会给传输的 HTTP 数据添加 HTTP 头部信息
- 传输层在应用程序数据前面增加了 TCP 头部(源端口,目的端口)
- 网络层在 TCP 数据包前增加了 IP 头部(源 IP 地址,目的地 IP 地址)
- 而数据链路层,又在 IP 数据包前后分别增加了以太网头部和尾部控制信息(源MAC 地址,目的 MAC 地址)
这些在头部或尾部增加的控制信息,增加了原始数据包的大小,但是物理链路中并不能传输任意大小的数据包。
数据链路层配置的最大传输单元(MTU,Maximum Transmission Unit)规定了最大的 IP 包大小。在我们最常用的以太网中,MTU 默认值是 1500 字节(这也是 Linux 的默认值)。
上图中 46~1500 怎么来的?
早期以太网使用共享链路,为保证 CSMA/CD 机制,规定以太帧长度最小为 64 字节,最大为 1518 字节。最小 64 字节是为保证极端冲突能被检测到,最大不超过 1518 字节是为防止过长帧占用共享链路时间过长导致阻塞。
以太网最大数据帧为 1518 字节,刨去帧头和帧尾,承载上层 IP 报文的地方最大为 1500 字节,即以太网默认 MTU 值。最少为 64-18=46。
这个MTU是网络层协议非常关心的地方,因为网络层协议比如IP协议会根据这个值来决定是否把上层传下来的数据进行分片,如果单个IP报文长度大于MTU,则会在发送出接口前被分片,被切割为小于或等于MTU长度的IP包。
显然,MTU 越大,需要的分包也就越少,自然,网络吞吐能力就越好。
当接收方主机接收到数据包时,会按照与封包相反的顺序,从协议栈自下而上逐步进行解包操作:
- 先从数据链路层将数据包组装起来,并提取出 IP 层的数据包;
- 接着去掉 IP 层的头部,获取传输层的数据包;
- 最后再从传输层的数据包中取出应用层的数据。