TCP/IP协议模型详解(精心整理)

“TCP/IP协议”可谓是我们日常工作中接触到的最多的数据传输协议了,也是在网络访问过程中的底层协议。可能很多小伙伴也跟我一样虽然对这个“协议”很熟悉,却傻傻分不清楚这个东西到底是什么以及整个工作流程是怎么样的,在拖延了也迷迷糊糊的用了无数天之后,终于下定决心好好梳理一番协议相关的知识。在拜读了无数前辈们辛苦整理的文章和帖子之后,最终写下本篇文章详细的梳理一下“TCP/IP协议”到底是什么以及整个工作流程,一是加深自己的学习印象,二来作为自己学习的记录,方便日后回顾重温。

本篇文章仅仅针对网络协议小白,很多知识都比较基础,可能也会有点啰嗦,但尽可能使用浅显易懂的语言来描述清楚,如有不足之处欢迎指正。

首先我们要弄清楚一个定义:
我们常说的TCP/IP不是一个协议,而是一个协议模型。
TCP/IP 的定义为传输控制协议/网络协议模型(Transmission Control Protocol/Internet Protocol)(不要被他长长的名字吓到了,只是一个模型的官方名,大部分的时间我们都统称为TCP/IP协议)。
这个模型描述了数据在网络传输的整个流程,可以简单理解为【程序发起数据传输请求、通过端口将数据发出、通过网络传递、接受程序收到数据】这个流程的模型。在这个模型里面用到了很多协议,但是TCP、IP协议在整个模型中占比最为重要,所以整个模型以TCP/IP来命名。
也有人把TCP/IP作为一个协议族的统称,里面包括了 IP 协议、IMCP 协议、TCP 协议、以及 http、ftp、pop3 协议等,这些都是在TCP/IP协议模型里使用到的协议。

与之相关的还有一个协议模型我们可以简单了解下–OSI/RM:开放系统互连基本参考模型(Open systems Interconnection Reference Model),简称为OSI。这个模型在1983正式成为国际标准,但是在这个模型发布之前因特网已经大范围的发布了,当时的因特网采用的TCP/IP协议模型,所以TCP/IP协议成为了使用范围最广的协议标准模型,也在1984年成为美国的计算机网络标准,而OSI则就不了了之了。

好了,进入正题,先用一个简单的数据请求流程图来了解一下TCP/IP协议模型:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0LMERkJ8-1596779437291)(https://upload-images.jianshu.io/upload_images/1232108-1b3945ac63dd12f0.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)]这个图简单描述了一下整个TCP/IP模型的一次数据传递流程,可能对添加的一些请求头有点陌生之外,对于整个业务流程我们还是可以容易的理解的,会有一些新名词和术语,不要着急,对于每一步我们后面都会详细的解析,先看明白这是一个常用的请求流程就好。
我们都听说过TCP/IP协议是分层的,如果把分层的概念用到我们的图上的话,就是下图所示:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jP7s7ezb-1596779437292)(https://upload-images.jianshu.io/upload_images/1232108-96945876dbe19460.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)]可以看到使用TCP/IP协议对我们的业务进行划分,可以分出来四层,分别是:应用层、传输层、网络层、链路层。(很多人对于分层的命名会有不同,但是每层的功能和含义是一样的)
互联网中信息以数据包的单位传输,不同的协议层对数据包有不同的称谓,在传输层叫做段 (segment),在网络层叫做数据报 (datagram),在链路层叫做帧 (frame)。

还有一个图可以对整个流程进行比较清晰的概括:TCP/IP协议模型详解(精心整理)一共四层,可以看到在每一层都会添加或者剥离不同的头部进行数据的发送和解析,再来一张百度大大清晰的数据结构层面的流程图:TCP/IP协议模型详解(精心整理)在每一层都会封装进去这一层的首部信息,最终封装完成的数据以帧的形式在外部网络通过网线、无线网等方式进行传输,最终接受方会一层层剥离信息拿到原始的数据给程序使用。

光明正大的再拿百度大大一张图,还是那句话,对里面的一些名字和缩写不用在意,后面我们都会讲解,其实并不复杂:TCP/IP协议模型详解(精心整理)
相信通过以上的几个图片大家对于网络分层的概念和每一层进行的操作已经很清楚了,先简单说一下每层大概的作用吧(以接收数据的路线来看),对整体流程有个大概的认识,后面会对每一层的功能和作用以及涉及到的相关知识点进行详细的解读:
链路层:
链路层负责将封装完的数据帧在网络中(网线等各种传输介质)进行传递
网络层:
网络层负责接收来自链路层的数据,然后通过IP地址和MAC地址找到目标主机,然后将数据传递给对应的主机
传输层:
传输层负责接收来自网络层的数据,然后根据端口号将数据传递给目标端口,监听该端口的程序即可收到该数据
应用层:
应用层的程序负责接收到数据后进行解析使用

每一层还是比较容易理解的吧,接下来我们看看每一层的详细解析,从链路层-网络层-传输层-应用层的顺序讲解:
#####链路层
链路层的作用是接受上一层传过来的数据包并通过网络发送出去或者从网络上接受物理帧,抽出IP数据包交给网络层处理,网络层再传递给传输层,传输层再传递给应用层进行数据解析处理。

网络层包括网络使用的硬件设备比如路由,网卡(NIC,network interface card)及网线等可见部分,还包括协议这种不可见部分,使用的协议取决于使用的是哪种网络。如果物理网络是LAN,那么通常使用的是以太网协议(802.3)和他的变体,如果使用的是WAN,常用的则是点对点协议(PPP)以及帧中继等协议。
其中最出名的是以太网协议,以太网协议通过网卡来进行数据通信。每个网卡都有自己的独特的一个地址,就是MAC地址。以太网数据以帧为单位,包括标头和数据部分。以太网在子网内通过广播的形式发送数据,如果两台设备在同一个子网里的话可以正常进行数据通信,但是如果这两台设备不在一个子网里的话就无法进行数据传输了,以太网协议就无法进行数据通信了。这就需要通过网络层来区分每台设备所在的网络是哪个子网,如果在同一个子网就通过广播发送数据,不在同一个子网就通过路由发送数据。这就导致了网络层的产生。(每个子网有自己的IP地址,可以通过IP地址进行查找和区分)

说一个子网在生活中的例子:
比如机场系统是将IP地址的主机编码分出一些位来挪用为子网编码。
  我们可以在172.50.0.0地址中,将第3个字节挪用出来表示各个子网,而不再分配给主机地址。这样,我们可以用172.50.1.0表示郑州机务段的子网,172.50.2.0分配给济南机务段作为该子网的网络地址,172.50.3.0分配给长沙机务段作为长沙机务段子网的网络地址。于是,172.50.0.0网络中有172.50.1.0、172.50.2.0、172.50.3.0…等子网。

再举一个子网的例子:
我们自己可以通过公司内和自己连接在一个无线网下的同事查询对比公网IP,会发现同处于一个无线网下的机器通过百度查询IP地址的时候(直接在百度输入IP搜索),查询的结果为路由器连接的公网IP地址,会查询出同样的结果,因为我们都处于路由器的子网之下。但是每台机器都会有一个路由器分配的本机IP地址,用来进行数据发送和接收,这个就是同一个子网下的不同机器分配了不同的子网Ip地址。

#####网络层
网络层的作用是:两台主机之间的数据传输需要知道对方的IP地址及MAC地址才可以进行传输。发送端的主机通过Ip地址找到局域网服务器的地方,然后通过ARP协议查询局域网路由器获取到目标主机的MAC地址,接着进行数据传输。局域网路由器记录目标主机的IP地址的操作是发生在目标主机接入局域网路由器的时候会通过RARP协议将自己的MAC地址(主机的mac地址是跟自己的网卡一一对应的,厂家出厂的时候就确定了)递交上去,获取到局域网路由器给自己分配的一个子网IP,在这个过程中目标主机的MAC地址被记录在了局域网路由器的映射表里。至于什么是ARP协议和为什么需要使用IP和MAC地址进行通信下面会详细讲解。网络层的主要作用就是确定每个数据包的发送路线,这个主机可以在同一个网络也可能外部网络,因此需要先区分主机是不是在同一个子网。

这一层常见协议:IP(Internet Protocol)、ICMP、ARP(Address Resolution Protocol)、RARP(Reverse ARP)。
IP是网络层的核心,通过路由选择将下一条IP封装后交给链路层。ICMP是网络层的补充,可以回送报文,用来检测网络是否畅通。

IP 地址是门牌号,而 IP 协议负责计算并找到指定门牌,快递小哥每天出门前要做的事就是 IP 协议的天职:分拣包裹、规划路径。其实,三五个节点的小型网络内部通信完全不必使用 IP 协议,因为这些节点之间本来就能两两互通,但会有个问题:节点数变多后,网速就会瘫痪,因为带宽耗尽。(带宽指固定时间内能传递的数据包,有点像马路宽度。)
因此,后来一片网络拆分成很多子网络(sub networks),每片子网络交给一台路由器统管。子网络中的节点间可以单独通信,不需要 IP 协议,但由于带宽限制,如果你想和本网络外的节点沟通时,就得使用一个设备:路由器。世界上大多数的路由器被几家大运营商掌管。TCP/IP协议模型详解(精心整理)
如上图,节点 1 和 2 同属一个子网,可基于内部通信协议沟通,而 1 和 5 间的联络必须基于 IP 协议,通过路由器 1 和 2 之间的路径交流。
把 IP 协议的逻辑推广到整个互联网,最终,连接我们手机客户端和腾讯服务器的是无数个路由器。TCP/IP协议模型详解(精心整理)
把大网络切小的好处显而易见:节约带宽、抬高网速,同时一只路由器挂了不影响其他节点间的通信,这就是 IP 协议的作用。

还有一些协助IP工作的协议,比如ARP和RARP,保证数据的传递除了需要IP地址还需要MAC地址,MAC地址又称物理地址,跟网卡一一对应,由生产厂家来确定,对于一台主机来说是唯一且不可变的,IP地址根据网络的不同是可变的。

上面两个协议简单来说就是:用IP地址找MAC地址(ARP);用MAC地址找IP地址(RARP)

“ARP(地址解析协议)基本功能就是通过目标设备的 IP 地址,查询目标设备的 MAC 地址,以保证通信的顺利进行。以太网中的数据帧从一个主机到达网内的另一台主机是根据48位的以太网地址(硬件地址)来确定接口的,而不是根据 32 位的 IP 地址。内核必须知道目的端的硬件地址才能发送数据。P2P 的连接是不需要 ARP 的。 (通过网关服务器的查询对应的MAC地址)

扩展:
地址解析协议,即ARP(Address Resolution Protocol),是根据IP地址获取物理地址的一个TCP/IP协议主机发送信息时将包含目标IP地址的ARP请求广播到网络上的所有主机,并接收返回消息,以此确定目标的物理地址;收到返回消息后将该IP地址和物理地址存入本机ARP缓存中并保留一定时间,下次请求时直接查询ARP缓存以节约资源。地址解析协议是建立在网络中各个主机互相信任的基础上的,网络上的主机可以自主发送ARP应答消息,其他主机收到应答报文时不会检测该报文的真实性就会将其记入本机ARP缓存;由此攻击者就可以向某一主机发送伪ARP应答报文,使其发送的信息无法到达预期的主机或到达错误的主机,这就构成了一个ARP欺骗ARP命令可用于查询本机ARP缓存中IP地址和MAC地址的对应关系、添加或删除静态对应关系等。相关协议有RARP代理ARPNDP用于在IPv6中代替地址解析协议。

RARP(反向地址转换协议)允许局域网的物理机器从网关服务器的 ARP 表或者缓存上请求其 IP 地址。局域网网关路由器中存有一个表以映射 MAC 和与其对应的 IP 地址。当设置一台新的机器时,其 RARP 客户机程序需要向路由器上的 RARP 服务器请求相应的 IP 地址。假设在路由表中已经设置了一个记录,RARP 服务器将会返回 IP 地址给机器。”

既然通信的最终结果都是通过MAC地址进行通信,为什么不直接使用MAC地址来进行通信呢?
最早这个世界上的电脑没这么多的时候,是没有路由这个东西存在的,主机都在一张网里,所以确实是直接通过 mac 地址通信的。最初的链路层协议是和 ip 地址无关的,没有网络层方面的设定,只有物理层和链路层,最初也只有集线器,没有交换机路由器,服务器之间传输数据全靠 mac 地址。在没有 ip 地址之前,mac 地址已经在使用了。现在到处都在用的二层交换机,就是根据 mac 地址转发数据。mac 地址的设计不携带设备在网络中的位置信息,想要通过 mac 地址通信,我们得在所有的设备上维护一张很大的表,记录所有 mac 地址路由在当前位置的的下一跳,这显然是不合理的。
MAC 地址结构一共有 48bit,分为两部分,前 24bit 是厂商代码,后 24bit 是厂家自己分配的。假如我们认为 MAC 地址可以区分不同的网络的话,那只能是使用厂商代码来区分不同的网络,显然同品牌网卡不代表在同一个网络。

引用大佬举的一个清晰明了的例子:
MAC 地址就像电脑的个人身份证,IP 地址就像电脑所在的屋子,屋子里可以住着很多人,局域网关路由就像登记人口的街道办公室。

#####传输层
传输层的作用是将接收到的数据发送给对应的程序,它建立端口到端口的链接(这个端口并不是说的主机的硬件端口,而是软件端口)。网络层建立主机到主机的连接,只要有主机和端口,就能确定数据包是属于哪个程序的,同时他也负责接收应用层的数据,然后把他们分成更小的单元(标头和数据部分在网络层的数据部分)传输到网络层。每个程序都会监听一个端口,接收来自这个端口的数据,所以传输层是建立端口到端口的链接。

传输层负责为我们的请求添加TCP头部,TCP我们用到的主要有两个协议:TCP和UDP协议。
TCP协议是一种可靠的、面向链接的基于字节流的传输协议。
可靠的指的是在传输服务过程中通过我们常说的三次握手、四次挥手来保证数据准确送达,但是网络的不稳定性并不保证他一定是准确送达的,但是这种机制是可靠的;
字节流传输指的是将大块数据分割成以报文段(segment)为单位的数据包进行管理传输,它把数据切成一个个数据包,从第一只数据包开始传,传送成功就翻倍,发现失败就从失败那只数据包重新开始,一直到传输完成。

为什么要有端口:
“ip 能锁定一台物理机器,对应着一张网卡,外界发来的数据包网卡都会接收。但是问题来了,网卡给程序提供了接口,你监听一下我,要是有消息来了,我就转发给你。这样应用程序就能收到数据了。但是问题来了,程序 A 和程序 B 都需要监听网卡接发数据,网卡说那我把接到的数据都发给你两,你们自己看着办吧。好,小 A 小 B 都接受了。但是又来了 CDEF…,不行了,每个包都被发到了所有应用程序,每个应用程序都累得不行,最终垮了。
好,那网卡说我给你们加个表示吧,我们之间可以用一个号码来作为标识,我和小 A 之间就用 1 来标识,如果外界发给 1 号标识的数据我就转发给你,你监听我的时候得告诉我你监听的时 1,我就转发 1 的数据包给你。好了其他的 BCD… 都自己弄一个标识号,只要不重复就行。这样大家都省事了。
最后设计到安全,一个标识号只能被一个应用程序监听,因为如果小 A 程序和小 B 同时监听一个标识号号,那就坏了,我传的数据都被 AB 接到,这样数据安全性就没办法保证了。”
参考《为什么要有端口,怎么来规划端口,看下边。》

TCP的三次握手与四次挥手

三次握手(开始连接):
第一次握手:客户端发送 syn 包 (syn=j) 到服务器,并进入 SYN_SEND 状态,等待服务器确认;
第二次握手:服务器收到 syn 包,必须确认客户的 SYN(ack=j+1),同时自己也发送一个 SYN 包(syn=k),即 SYN+ACK 包,此时服务器进入 SYN_RECV 状态;
第三次握手:客户端收到服务器的 SYN+ACK 包,向服务器发送确认包 ACK(ack=k+1),此包发送完毕,客户端和服务器进入 ESTABLISHED 状态,完成三次握手。
注意:握手过程中传送的包里不包含数据,三次握手完毕后,客户端与服务器才正式开始传送数据。除了上述三次握手,TCP 协议还有其他各种手段来保证通信的可靠性。
理想状态下,TCP 连接一旦建立,在通信双方中的任何一方主动关闭连接之前,TCP 连接都将被一直保持下去。
断开连接时服务器和客户端均可以主动发起断开 TCP 连接的请求,断开过程需要经过“四次握手”。
来一张图:TCP/IP协议模型详解(精心整理)

四次挥手(关闭连接):
第一次: 当主机A完成数据传输后,将控制位FIN置1,提出停止TCP连接的请求 ;
第二次: 主机B收到FIN后对其作出响应,确认这一方向上的TCP连接将关闭,将ACK置1;
第三次: 由B 端再提出反方向的关闭请求,将FIN置1 ;
第四次: 主机A对主机B的请求进行确认,将ACK置1,双方向的关闭结束.。

由TCP的三次握手和四次断开可以看出,TCP使用面向连接的通信方式, 大大提高了数据通信的可靠性,使发送数据端和接收端在数据正式传输前就有了交互, 为数据正式传输打下了可靠的基础。

名词解释
1、ACK 是TCP报头的控制位之一,对数据进行确认。确认由目的端发出, 用它来告诉发送端这个***之前的数据段都收到了。 比如确认号为X,则表示前X-1个数据段都收到了,只有当ACK=1时,确认号才有效,当ACK=0时,确认号无效,这时会要求重传数据,保证数据的完整性。
2、SYN 同步***,TCP建立连接时将这个位置1。
3、FIN 发送端完成发送任务位,当TCP完成数据传输需要断开时,,提出断开连接的一方将这位置1。

至于 UDP 协议,传送数据前并不与对方建立连接,对接收到的数据也不发送确认信号,发送端不知道数据是否会正确接收,当然也不用重发,所以说 UDP 是无连接的、不可靠的一种数据传输协议。具体据知乎用户陈宝佳的帖子,UDP 传输的信息包最小只有 8 个字节,TCP 则是 20 个字节。这样的好处是,UDP 对系统资源要求更低,开销更小,数据传输速率更高,因为不必进行收发数据的确认,所以 UDP 的实时性更好。他还表示 MSN 采用 TCP 传输协议传文件,QQ 传输文件采用 UDP,所以后者更快。
TCP/IP协议模型详解(精心整理)
我们经常用的 ping 命令的原理就是向对方主机发送 UDP 数据包,然后对方主机确认收到数据包, 如果数据包是否到达的消息及时反馈回来,那么网络就是通的。ping 命令是使用 IP 和网络控制信息协议 (ICMP),因而没有涉及到任何传输协议(UDP/TCP) 和应用程序。它发送 icmp 回送请求消息给目的主机。ICMP 协议规定:目的主机必须返回 ICMP 回送应答消息给源主机。如果源主机在一定时间内收到应答,则认为主机可达。TCP/IP协议模型详解(精心整理)
TCP/IP协议模型详解(精心整理)

#####应用层
应用层就是我们最经常接触的地方,也是比较简单的一层。这一层的主要作用就是将我们的数据根据我们使用的协议打包或者按照协议解析从传输层过来的各种类型的数据数据,主要协议有:HTTP、FTP、SMTP、Telnet、NFS、RIP 等等。比如我们开发中用到较多的http请求进行数据包装、发邮件用到的SMTP、文件传输用到的FTP协议等,都是在这一层进行封装的,封装完后传入传输层开始数据的传递。

结语:
以上就是对TCP/IP协议讲解的全部内容了,后面会继续更新TCP协议和UDP协议的相关内容。
本篇文章很多内容参阅了前辈的文章,甚至有些地方感觉写的实在精彩是直接拷贝过来的,感谢留下墨宝的前辈大佬。

相关阅读请移步:
一文看懂互联网TCP/IP协议 | 小明学习笔记
一分钟了解 TCP/IP 模型
TCP和UDP的区别
计算机网络结构模型TCP/IP详解
TCP的三次握手与四次挥手理解及面试题(很全面)
TCP/IP协议(百度百科)