0
点赞
收藏
分享

微信扫一扫

详解TCP报文格式以及TCP相关特性

小美人鱼失去的腿 2024-01-11 阅读 19

目录

一、 TCP协议段格式

1.1 TCP协议格式 

二、TCP原理 (基本机制/特性)

2.1 确认应答机制 

2.2 超时重传机制 (安全机制)

2.3 连接管理机制(安全机制) 

2.4 滑动窗口(效率机制) 

2.5 流量控制(安全机制) 

 2.6 拥塞控制(安全机制)

 2.7 延时应答(效率机制)

2.8 捎带应答(效率机制) 

三、粘包问题 

四、TCP异常情况 

五、TCP小结


TCP是传输层的重点协议,对于我们了解网络原理有着至关重要的作用。 

一、 TCP协议段格式

TCP 协议

TCP ,即 Transmission Control Protocol ,传输控制协议。人如其名,要对数据的传输进行一个详细的控制。

1.1 TCP协议格式 

  • /目的端口号:表示数据是从哪个进程来,到哪个进程去
  • 32位序号/32位确认号:后面详细给大家介绍
  • 4位首部长度:表示该TCP头部有多少个32bit(有多少个4字节),所以TCP头部最大长度是 15 * 4 = 60
  •  6位标志位:
  • 16位窗口大小:流量控制(下面我会详细介绍)
  • 16位校验和:发送端填充,CRC校验。接收端校验不通过,则认为数据有问题。此处的检验和不光包含TCP首部,也包含TCP数据部分
  • 16位紧急指针:标识哪部分数据是紧急数据
  • 40字节头部选项:暂时忽略

二、TCP原理 (基本机制/特性)

TCP 对数据传输提供的管控机制,主要体现在两个方面:安全和效率。这些机制和多线程的设计原则类似:保证数据传输安全的前提下,尽可能的提高传输效率。

2.1 确认应答机制 

 TCP将每个字节的数据都进行了编号,即为序列号,但是并不会真正的存储每个字节的序列号,只需要保存起始序号,通过TCP的报文长度来+ 起始序号得到最后一个字节的编号。

每一个 ACK 都带有对应的确认序列号,意思是告诉发送者,我已经收到了哪些数据,下一次你从哪里开始发。

2.2 超时重传机制 (安全机制)

但是,主机 A 未收到 B 发来的确认应答,也可能是因为 ACK 丢失了:

此时也会触发主机A重发, 因此主机 B 会收到很多重复数据。那么 TCP 协议需要能够识别出那些包是重复的包,并且把重复的丢弃 掉。 这时候我们可以利用前面提到的序列号,就可以很容易做到去重的效果。  

那么,如果超时,这个时间如何确定? 

TCP为了保证无论在任何环境下都能比较高性能的通信,因此会动态计算这个最大超时时间。 

2.3 连接管理机制(安全机制) 

在正常情况下, TCP 要经过三次握手建立连接,四次挥手断开连接。

三次握手:

四次挥手:

 

服务端状态转化:  

客户端状态转化: 

为什么是TIME_WAIT的时间是2MSL? 

关于CLOSE_WAIT  

2.4 滑动窗口(效率机制) 

刚才给大家介绍了确认应答策略,对每一个发送的数据段,都要给一个 ACK 确认应答。收到 ACK 后再发送下一个数据段。这样做有一个比较大的缺点,就是性能较差。尤其是数据往返的时间较长的时候。

既然这样一发一收的方式性能较低,那么我们一次发送多条数据,就可以大大的提高性能(其实是将多个段的等待时间重叠在一起了)。

 那么如果出现了丢包,如何进行重传?这里分两种情况讨论:

情况一:数据包已经抵达,ACK被丢了。

这种情况下,部分ACK丢了并不要紧,因为可以通过后续的ACK进行确认。

情况二:数据包丢失

这种机制被称为 "高速重发控制"(也叫 "快重传")。

2.5 流量控制(安全机制) 

接收端处理数据的速度是有限的。如果发送端发的太快,导致接收端的缓冲区被打满,这个时候如果发送端继续发送,就会造成丢包,继而引起丢包重传等等一系列连锁反应。

因此 TCP 支持根据接收端的处理能力,来决定发送端的发送速度。这个机制就叫做 流量控制。

接收端如何把窗口大小告诉发送端呢?在上面的 TCP 首部(报头)中,有一个 16位窗口字段,就是存放了窗口大小信息。那么问题来了, 16 位数字最大表示 65535 ,那么 TCP 窗口最大就是 65535 字节么?

 2.6 拥塞控制(安全机制)

        虽然 TCP有了滑动窗口这个大杀器,能够高效可靠的发送大量的数据。但是如果在刚开始阶段就发送大量的数据,仍然可能引发问题。 因为网络上有很多的计算机,可能当前的网络状态就已经比较拥堵。在不清楚当前网络状态下,贸然发 送大量的数据,是很有可能引起雪上加霜的。 因此TCP 引入 慢启动 机制,先发少量的数据,探探路,摸清当前的网络拥堵状态,再决定按照多大的速度传输数据。

        像上面这样的拥塞窗口增长速度,是指数级别的。"慢启动" 只是指初始时慢,但是增长速度非常快。 为了不增长的那么快,因此不能使拥塞窗口单纯的加倍。此处引入一个叫做慢启动的阈值 ,当拥塞窗口超过这个阈值的时候,不再按照指数方式增长,而是按照线性方式增长。

        少量的丢包,我们仅仅是触发超时重传,大量的丢包,我们就认为网络拥塞。当TCP通信开始后,网络吞吐量会逐渐上升,随着网络发生拥堵,吞吐量会立刻下降。 拥塞控制,归根结底是 TCP 协议想尽可能快的把数据传输给对方,但是又要避免给网络造成太大压力的 折中方案。

 2.7 延时应答(效率机制)

如果接收数据的主机立刻返回 ACK 应答,这时候返回的窗口可能比较小。

窗口越大,网络吞吐量就越大,传输效率就越高。我们的目标是在保证网络不拥塞的情况下尽量提高传输效率。

那么所有的包都可以延迟应答么?肯定也不是:

 具体的数量和超时时间,依操作系统不同也有差异,一般N2,超时时间取200ms。

2.8 捎带应答(效率机制) 

        在延迟应答的基础上,我们发现很多情况下,客户端服务器在应用层也是 " 一发一收 " 的。意味着客户端给服务器说了 "How are you"(请求) ,服务器也会给客户端回一个 "Fine, thank you"(响应),那么这个时候ACK 就可以搭顺风车,和服务器回应的 "Fine thank you" 一起回给客户端

三、粘包问题 

那么如何避免粘包问题呢?归根结底就是一句话,明确两个包之间的边界

 思考:对于UDP协议来说,是否也存在 "粘包问题" 呢?

四、TCP异常情况 

  • 进程终止:进程终止会释放文件描述符,仍然可以发送FIN。和正常关闭没有什么区别。
  • 机器重启:和进程终止的情况相同。

  • 机器掉电/网线断开:接收端认为连接还在,一旦接收端无写入操作,就可以发现连接已经不在了,就会进行reset。即使没有写入操作,TCP自己也内置了一个保活定时器(心跳包),会定期询问对方是否还在。如果对方不在,也会把连接释放。

五、TCP小结

为什么 TCP 这么复杂?因为要保证可靠性,同时又尽可能的提高性能。

可靠性:

  • 校验和
  • 序列号(按序到达)
  • 确认应答
  • 超时重发
  • 连接管理
  • 流量控制
  • 拥塞控制

提高性能: 

  • 滑动窗口
  • 快速重传
  • 延迟应答
  • 捎带应答

其他:

  • 定时器(超时重传定时器,保活定时器,TIME_WAIT定时器等) 

举报

相关推荐

0 条评论