TCP协议讲解-----了解TCP可靠性的基石

个人主页:小则又沐风

个人专栏:
[数据结构](https://blog.csdn.net/jiaomorning/category_13115833.html?fromshare=blogcolumn&sharetype=blogcolumn&sharerId=13115833&sharerefer=PC&sharesource=jiaomorning&sharefrom=from_link "数据结构")
[竞赛专栏](https://blog.csdn.net/jiaomorning/category_13117056.html?fromshare=blogcolumn&sharetype=blogcolumn&sharerId=13117056&sharerefer=PC&sharesource=jiaomorning&sharefrom=from_link "竞赛专栏")
[C语言](https://blog.csdn.net/jiaomorning/category_13115832.html?fromshare=blogcolumn&sharetype=blogcolumn&sharerId=13115832&sharerefer=PC&sharesource=jiaomorning&sharefrom=from_linkhttps://blog.csdn.net/jiaomorning/category_13115832.html?fromshare=blogcolumn&sharetype=blogcolumn&sharerId=13115832&sharerefer=PC&sharesource=jiaomorning&sharefrom=from_link "C语言")
[C++](https://blog.csdn.net/jiaomorning/category_13141438.html "C++")
[Linux](https://blog.csdn.net/jiaomorning/category_13157216.html "Linux")
[OJ项目](https://blog.csdn.net/jiaomorning/category_13197107.html "OJ项目")
[MySQL](https://blog.csdn.net/jiaomorning/category_13202545.html "MySQL")

[GIT](https://blog.csdn.net/jiaomorning/category_13205841.html "GIT")


前言:

我们熟知的传输层协议有 UDP 和 TCP。

UDP 我们知道他的优点就是简单高效。

相较于UDP,TCP的优点就是连接更加稳定。但是我们这些概念只是道听途说,并不知道TCP连接的稳定性到底是怎么保证的。

今天我们就深入到 TCP 的原理中,逐步剖析 TCP 的核心。

我们先来看这一张图片

我们从上述的这张图片中,我们可以知道的是:

我们在进行通信的时候,我们调用的 write、read 这种的系统调用是直接从网络中获取到的信息吗?

不是的.

它们只是从自己的本地缓冲区中拷贝过来的。但是是什么把信息从网络中转移到缓冲区中的呢?

这就是我们今天的介绍的对象了----传输层(TCP)

我们知道在网络通信中TCP扮演的对象就是一个搬运工呗.

但是这个搬运工是怎么知道从哪里来到哪里去.对方需要我搬多少,以及搬运工是否半路走丢等等这些问题呢?

TCP协议段格式

我们来逐步的分析TCP协议

源/目的端口号

总的来说就是:

源端口号记录的是发送方的,目的端口号记录的就是目的地的.

我们来看这样的例子.

为什么唐僧总是说这样的话:

贫僧自东土大唐而来,要前往西天取经.

这句话看起来简单,但是她的信息量都有什么?

源端口号:东土大唐

目的端口:西天

32位序号/确认序号

这个序号的设计是保证TCP协议稳定性的基础.

需要知道的是UDP协议是面向数据报的.但是TCP是面向字节流的.

也就是说TCP传输的数据是按照字节为单位的.

用一句话形象地来形容,就像一条河流一样。

但是与杂乱无序的河流相比TCP将自己的每一个字节都进行了编号.

那么这样的设计有什么作用呢?

首先为什么我们将这个设计和可靠性挂钩呢?

在32位序号中,发送方会指出自己发送数据的区间,例如:1000-1199

如果对方的确是收到了上面的数据的话,就会在确认序号中发送1200表示1200序号之前的数据我都收到了,之后你就从1200发送就可以了.

如果我们发送的数据丢失了呢?

发送:1000-1200 1200-1400 1400-1600

收到:1000-1200 1400-1600

那么确认序号就是1200,我们就需要从1200开始重新发送数据

(后面在讲解滑动窗口的时候我们还会进行讲解的)

另外这样的设计还有的优点就是,对于数据我们知道了他的编号的话,数据的顺序不会杂乱了.

防止重复数据包:网络延迟导致旧包迟到,接收方通过序号判断这包是不是过期重复包,丢弃重复数据

4 位首部长度(重点)

可以看到的是在TCP的协议中,有一个名为选项的空间,但是这个空间的大小是不确定的,那么我们这样就无法正确的把数据和报头分隔开来,所以我们就需要借助4位首部长度来解决上述的问题.

实际上这个就是4位的二进制.但是他的单位是4字节.他的作用就是用来统计当前报文中头部的长度的.

需要知道的是一个TCP空报头是20字节的.

所以向对方发送一个空报头4位首部就是20/4=5;

5对应的二进制是0101.

4位首部的取值范围是0-15

所以我们计算的结果的范围就是0-60

但是一个空报头的大小就是20所以实际上的范围就是20-60

6 位标志位

在通信的过程中,会有不同的信息类型,在TCP中,对不同类型的信息进行了标志.

  • URG:紧急指针有效
  • ACK:确认序号有效(所有数据传输阶段的报文都必须置 1)
  • PSH:提示接收端立即将数据从 TCP 缓冲区推送给应用层
  • RST:强制重置连接
  • SYN:请求建立连接
  • FIN:请求关闭连接

TCP和UDP的区别

造成TCP和UDP有区别的关键就是:

TCP是面向字节流,TCP只对传输的信息将报头和报文进行了分割,但是没有做报文之间的分隔,所以对TCP报文进行分割是应用层的工作.

UDP是面向数据报的,UDP中的一个信息就是存储了UDP报文的大小,并且UDP的报头长度是一个固定的8字节.所以我们可以说的就是UDP报文是"粒粒分明"的.

TCP 可靠性核心:确认应答与超时重传

都说TCP协议可靠性高,但是是什么样的设计来支撑起他的可靠性呢?

那就是TCP的应答机制了

我们在传输信息的时候我们最害怕的是什么?

那就是我们的数据在传输的时候数据丢失了,更加可怕的的就是我们还不知道数据是否丢了

举一个例子:

张三在路上遇到了李四.

张三说:你好啊,李四,这么巧.

李四收到之后说:你好啊.张三.

张三说:你吃饭了吗?要不要一起去吃饭?

张三的这句话传送过去之后,张三是认为对方收到的,但是如果李四没听到呢,会发生什么?

对于李四来说当他回答完你好啊之后,李四就认为通话结束了.

张三却不知道李四没收到.这就很尴尬了.

如果张三丢失的信息不是一个询问的,而是一个类似这样的:我在...等你,我们一起吃饭吧.

那么张三以为李四收到了,去约定的地点等待结果就是没有后续了.

这就是数据丢失造成的后果了.

那么为了应对这个情况,TCP规定在收到信息之后要进行确认应答.

准确的就是将报头中的标志位标上ACK,因为还有确认序号的存在,我们不仅可以让对方知道我们收到了信息,还可以让对方知道我们收到了那些的信息.

这样的机制保证了我们最新信息之前的信息都是没有丢失的(准确的来说是确认序号之前的),但是对于最新的信息却不能保证他的可靠性.

这就是确认应答机制.

但是还是出现了一个问题:

确认应答是真的收到了数据,但是数据真正丢失的话,对方不知道有数据过来就不会进行ACK,那么发送方是怎么知道数据丢失了呢?

这就是我们下面将要讲解的超时重传的机制了

我们回想一下日常情况下,你在和对方说话的时候,对方没有对你的话进行回答.

你的反应是:

说话->等待对方回答->对方没有回答->你继续等待->思考对方是不是没有听到->重复自己刚才的话

类似的道理,当我们的发送方在规定的时间内没有收到ACK,就会对信息进行重发.

当然是有两种情况的:

  • 接收方根本没有收到数据
  • 接收方收到了数据,但是他发送的ACK丢失了

这都被归类位数据丢失.发送方都没有收到ACK,都会进行重传.

总结

本文深入剖析了 TCP 协议的核心原理。首先介绍了 TCP 与 UDP 的基本差异,随后详细讲解了 TCP 协议段格式中的关键字段,包括源/目的端口号、32 位序号与确认序号、4 位首部长度以及 6 位标志位,并对比了 TCP 与 UDP 在面向字节流和面向数据报上的本质区别。最后重点阐述了 TCP 可靠性的两大核心机制------确认应答与超时重传.

相关推荐
刚入门的大一新生1 小时前
Linux-简单设计libc库
linux·c++
科小墨2 小时前
【Linux 开发者系列 · 第 1 节】NPM 完全指南:它是什么、为什么重要、在 Linux 上怎么用
linux
IT北辰2 小时前
Linux运维:sed命令修改配置文件IP
linux
牢姐与蒯2 小时前
Linux文件(三).Ext系列文件系统
linux·运维·服务器
2401_869769592 小时前
linux基本指令2
linux
?re?ta?rd?ed?2 小时前
五层网络结构图概念理解
linux
码少女3 小时前
Linux--套接字编程
linux·服务器·网络
进击的荆棘3 小时前
Linux系统——进程控制(下)
linux·运维·服务器·进程
爱网络爱Linux10 小时前
【系列】每天一个 Linux 命令(53)startx 命令
linux·rhce·rhca·linux运维·linux命令大全·红帽认证