深入理解TCP/IP模型

2,014 阅读13分钟

1 OSI七层模型的简单介绍

网络模型不是一开始就有的,在网络刚发展时,网络协议是由各互联网公司自己定义的,各家的协议也是不能互通的。这样大大的阻碍了互联网的发展,为了解决这个问题,国际标准化组织 1984 提出的模型标准,简称 OSI(Open Systems Interconnection Model)。具体如下图:

OSI七层模型

OSI七层模型每一层都有自己的作用,从上到下的作用依次为:

  • 应用层(Application) :提供网络与用户应用软件之间的接口服务
  • 表示层(Presentation) :提供格式化的表示和转换数据服务,如加密和压缩
  • 会话层(Session) 提供包括访问验证和会话管理在内的建立和维护应用之间通信的机制
  • 传输层(Transimission):提供建立、维护和取消传输连接功能,负责可靠地传输数据(PC)
  • 网络层(Network): 处理网络间路由,确保数据及时传送(路由器)
  • 数据链路层(DataLink): 负责无错传输数据,确认帧、发错重传等(交换机)
  • 物理层(Physics) :提供机械、电气、功能和过程特性(网卡、网线、双绞线、同轴电缆、中继器)

七层中应用层、表示层和会话层由软件控制,传输层、网络层和数据链路层由操作系统控制,物理层有物理设备控制。

2 TCP/IP参考模型及协议

1) 模型

TCP/IP 模型是由 OSI 模型演化而来,TCP/IP 模型将 OSI 模型由七层简化为五层(一开始为四层),应用层、表示层、会话层统一为应用层。

TCP/IP参考模型

2) 协议

TCP/IP协议被称为传输控制协议/互联网协议,又称网络通讯协议(Transmission Control Protocol)。是由网络层的IP协议和传输层的TCP协议组成,是一个很大的协议集合。

  • 物理层和数据链路层没有定义任何特定协议,支持所有的标准和专用的协议。

  • 网络层定义了网络互联也就是IP协议,主要包括IP、ARP、RARP、ICMP、IGMP。

  • 传输层定义了TCP和UDP(User Datagram Protocol),我们会后面重点介绍一下TCP协议。

  • 应用层定义了HTTP(超文本传输协议)、FTP(文件传输协议)、DNS(域名系统)等协议。

3 物理层

计算机在传递数据的时候传递的都是0和1的数字,而物理层关心的是用什么信号来表示0和1,是否可以双向通信,最初的连接如何建立以及完成连接如何终止,总之,物理层是为数据传输提供可靠的环境。

4 数据链路层

数据链路层们于物理层和网络层之间,用来向网络层提供数据,就是把源计算机网络层传过来的信息传递给目标主机。 数据链路层主要的作用包括:

  • 如何将数据组合成数据帧(Frame),帧是数据链路层的传输单位
  • 数据链路的建立、维护和拆除
  • 帧包装、帧传输、帧同步
  • 帧的差错恢复
  • 流量控制

5 网络层

网络层位于传输层和数据链路层之间,用于把数据从源主机经过若干个中间节点传送到目标主机,并向传输层提供最基础的数据传输服务,它要提供路由和选址的工作。

那什么是路由和选址呢?

选址

交换机是靠MAC来寻址的,而因为MAC地址是无层次的,所以要靠IP地址来确认计算机的位置,这就是选址。

路由

在能够选择的多条道路之间选择一条最短的路径就是路由的工作。

路由和选址都离不开IP,我们就详细介绍一下IP头部。

IP头

IP头部是由20个字节组成的,具体项所占的位数如下图:

IP头

具体的数据我们用Wireshark来表抓取一下,如图(蓝色部分为IP数据包):

IP抓包

version - 版本

Header Length - 首部长部

Differentiated Services Field - 优先级与服务类型

Total Length - 总长度,该字段用以指示整个IP数据包的长度,最长为65535字节,包括头和数据。

Identification - 标识符,唯一标识主机发送的每一份数据报。

Flags - 标志。分为3个字段,依次为保留位、不分片位和更多片位

Fragment offset - 段偏移量。该分片相对于原始数据报开始处位置的偏移量。

TTL(Time to Live生存时间) - 该字段用于表示IP数据包的生命周期,可以防止一个数据包在网络中无限循环地发下去。TTL的意思是一个数据包在被丢弃之前在网络中的最大周转时间。该数据包经过的每一个路由器都会检查该字段中的值,当TTL的值为0时此数据包会被丢弃。TTL对应于一个数据包通过路由器的数目,一个数据包每经过一个路由器,TTL将减去1。

Protocol - 协议号。用以指示IP数据包中封装的是哪个协议。

Header checksum - 首部校验和。检验和是16位的错误检测字段。目的主机和网络中的每个网关都要重新计算报头的校验和,如果一样表示没有改动过。

Source - 源IP地址。该字段用于表示数据包的源地址,指的是发送该数据包的设备的网络地址。

Destination - 目标IP地址。该字段用于表示数据包的目标的地址,指的是接收节点的网络地址。

6 传输层

传输层是面向连接的、可靠的的进程到进程通信的协议。TCP提供全双工服务,即数据可在同一时间双向传播。TCP将若干个字节构成一个分组,此分组称为报文段(Segment)。提供了一种端到端的连接。

传输层的协议主要有TCP 和 UDP,TCP(Transimision Control Protocal)是一种可靠的、面向连接的协议,传输效率低。UDP(User Datagram Protocal)是一种不可靠的、无连接的服务,传输效率高。 下面重点介绍一下TCP的三次握手和四次挥手。

1) TCP的功能

TCP主要是将数据进行分段打包传输,对每个数据包编号控制顺序,运输中丢失、重发和丢弃处理。

2) TCP头的介绍

有点和IP头类似,我们先来张图看下:

TCP头部

Source Port & Destination Port - 源端口号和目标端口号;计算机通过端口号识别访问哪个服务,比如http服务或ftp服务;发送方端口号是进行随机端口;目标端口号决定了接收方哪个程序来接收。

Sequence number - 32位序列号,TCP用序列号对数据包进行标记,以便在到达目的地后重新重装。在建立连接时通常由计算机生成一个随机数作为序列号的初始值。

Acknowledgment number - 32位确认号,确认应答号。发送端接收到这个确认应答后,可以认为这个位置以前所有的数据都已被正常接收。

Header Length - 首部长度。单位是 '4'个'字节',如果没有可选字段,那么这里的值就是 5。表示 TCP 首部的长度为 20 字节。

checksum - 16位校验和。用来做差错控制,TCP校验和的计算包括TCP首部、数据和其它填充字节。

flags - 控制位。TCP的连接、传输和断开都受这六个控制位的指挥

window size - 本地可接收数据的数目,这个值的大小是可变的。当网络通畅时将这个窗口值变大加快传输速度,当网络不稳定时减少这个值可以保证网络数据的可靠传输。它是来在TCP传输中进行流量控制的

3) 传说中的三次握手和四次挥手(抓包演示)

三次握手和四次挥手到底是怎么回事呢,我用一台主机A(172.16.50.72:65076)起一个服务,另外一台主机B(172.16.17.94:8080)请求一下。 在A主机上启动node服务:

let http = require('http');
let url = require('url');

let server = http.createServer();
server.on('request', (req, res) => {
    let {pathname, querry} = url.parse(req.url, true);
    let result = [];
    req.on('data', (data) => {
        result.push(data);
    })
    req.on('end', () => {
        console.log(Buffer.concat(result).toString());
        res.end('hello world');
    })

})
server.listen(8080, () => {
    console.log('server started');
});

B主机连接A并发送数据:

curl -d "user":"lucy" 172.16.17.94:8080

用wireshark抓包演示一下。如下图:

wireshark抓包演图

上图中A为三次握手,B为数据传输,C为四次挥手。下面我们详细介绍一下这三个部分。

首先我们先图解一下wireshark抓到的数据,如下图:

全部

我们把这个过程分为三部分,第一部分为三次握手建立连接,第二部分为数据传输,第三次为四次挥手断开连接。

三次握手

我们分析一下三次握手的过程(包括ack 和 seq的值变化),

三次握手
为了方便描述我们将主动发起请求的172.16.17.94:8080 主机称为客户端,将返回数据的主机172.16.17.94:8080称为服务器,以下也是。

  • 第一次握手: 建立连接。客户端发送连接请求,发送SYN报文,将seq设置为0。然后,客户端进入SYN_SEND状态,等待服务器的确认。

  • 第二次握手: 服务器收到客户端的SYN报文段。需要对这个SYN报文段进行确认,发送ACK报文,将ack设置为1。同时,自己还要发送SYN请求信息,将seq为0。服务器端将上述所有信息一并发送给客户端,此时服务器进入SYN_RECV状态。

  • 第三次握手: 客户端收到服务器的ACK和SYN报文后,进行确认,然后将ack设置为1,seq设置为1,向服务器发送ACK报文段,这个报文段发送完毕以后,客户端和服务器端都进入ESTABLISHED状态,完成TCP三次握手。

数据传输

数据传输

  • 客户端先向服务器发送数据,该数据报是lenth为159的数据。
  • 服务器收到报文后, 也向客户端发送了一个数据进行确认(ACK),并且返回客户端要请求的数据,数据的长度为111,将seq设置为1,ack设置为160(1 + 159)。
  • 客户端收到服务器返回的数据后进行确认(ACK),将seq设置为160, ack设置为112(1 + 111)。

四次挥手

当客户端和服务器通过三次握手建立了TCP连接以后,当数据传送完毕,就要断开TCP连接了,就有了神秘的“四次挥手”。

四次挥手

  • 第一次挥手:客户端向服务器发送一个FIN报文段,将设置seq为160和ack为112,;此时,客户端进入 FIN_WAIT_1状态,这表示客户端没有数据要发送服务器了,请求关闭连接;

  • 第二次挥手:服务器收到了客户端发送的FIN报文段,向客户端回一个ACK报文段,ack设置为1,seq设置为112;服务器进入了CLOSE_WAIT状态,客户端收到服务器返回的ACK报文后,进入FIN_WAIT_2状态;

  • 第三次挥手:服务器会观察自己是否还有数据没有发送给客户端,如果有,先把数据发送给客户端,再发送FIN报文;如果没有,那么服务器直接发送FIN报文给客户端。请求关闭连接,同时服务器进入LAST_ACK状态;

  • 第四次挥手:客户端收到服务器发送的FIN报文段,向服务器发送ACK报文段,将seq设置为161,将ack设置为113,然后客户端进入TIME_WAIT状态;服务器收到客户端的ACK报文段以后,就关闭连接;此时,客户端等待2MSL后依然没有收到回复,则证明Server端已正常关闭,客户端也可以关闭连接了。

注意:在握手和挥手时确认号应该是对方序列号加1,传输数据时则是对方序列号加上对方携带应用层数据的长度。

7 应用层

应用层常见协议有HTTP、HTTPS 、FTP 、SMTP等。

TCP/IP模型我们基本介绍完了,那层与层之间是怎样合作和分工的呢,我们用两张图介绍一下: 发送方的数据是从上往下传输的,即从应用层向物理层传输。接收方的数据是从下往上传输的,即从物理层向应用层传输。如下两张图。

从上到下

发送方是从高层到低层封装数据:

  • 在应用层要把各式各样的数据如字母、数字、汉字、图片等转换成二进制
  • 在TCP传输层中,上层的数据被分割成小的数据段,并为每个分段后的数据封装TCP报文头部
  • 在TCP头部有一个关键的字段信息端口号,它用于标识上层的协议或应用程序,确保上层数据的正常通信
  • 计算机可以多进程并发运行,例如在发邮件的同时也可以通过浏览器浏览网页,这两种应用通过端口号进行区分
  • 在网络层,上层数据被封装上亲的报文头部(IP头部),上层的数据是包括TCP头部的。IP地址包括的最关键字段信息就是IP地址,用于标识网络的逻辑地址。
  • 数据链路径层,上层数据成一个MAC头部,内部有最关键的是MAC地址。MAC地址就是固化在硬件设备内部的全球唯一的物理地址。
  • 在物理层,无论在之前哪一层封装的报文头和还是上层数据都是由二进制组成的,物理将这些二进制数字比特流转换成电信号在网络中传输

从下到上
接收方是从低层到高层解封装

  • 数据封装完毕传输到接收方后,将数据要进行解封装
  • 在物理层,先把电信号转成二进制数据,并将数据传送至数据链路层
  • 在数据链路层,把MAC头部拆掉,并将剩余的数据传送至上一层
  • 在网络层,数据的IP头部被拆掉,并将剩余的数据送至上一层
  • 在传输层,把TCP头部拆掉,将真实的数据传送至应用层

深入理解TCP/IP模型就简单介绍完了,如果有理解错误的地方,欢迎指正!

8 参考文章