TCP协议之如何保证传输的可靠性

一、问题

TCP协议之如何保证传输的可靠性?我们先看下TCP的头部图片和TCP头部的字段

/*TCP头定义,共20个字节*/
typedef struct _TCP_HEADER 
{
  short m_sSourPort;              // 源端口号16bit
  short m_sDestPort;             // 目的端口号16bit
  unsigned int m_uiSequNum;         // 序列号32bit
  unsigned int m_uiAcknowledgeNum;    // 确认号32bit
  short m_sHeaderLenAndFlag;        // 前4位:TCP头长度;中6位:保留;后6位:标志位
  short m_sWindowSize;            // 窗口大小16bit
  short m_sCheckSum;              // 检验和16bit
  short m_surgentPointer;          // 紧急数据偏移量16bit
} __attribute__((packed))TCP_HEADER, *PTCP_HEADER;

二、 保证可靠性的手段

1)、校验和(只要协议的包头里面有校验和都支持:比如TCP协议 UDP协议  IP协议)

校验和:发送的数据段都当做一个16位的整数,将这些整数加起来。并且前面的进位不能丢弃,补在后面,最后取反,得到校验和。 

 收方比对校验和与发送方不一致,那么数据一定传输有误。但是如果接收方比对校验和与发送方一致,数据不一定传输成功

2)、确认号与序列号(TCP协议包头里面分别是32位,序列号去掉服务端收到的重复数据)

序列号:TCP传输时将每个字节的数据都进行了编号,这就是序列号(通过序列号可以去重)
确认应答:TCP传输的过程中,每次接收方收到数据后,都会对传输方进行确认应答。也就是发送ACK报文。这个ACK报文当中带有对应的确认序列号,告诉发送方,接收到了哪些数据,下一次的数据从哪里发。

序列号的作用不仅仅是应答的作用,有了序列号能够将接收到的数据根据序列号排序,并且去掉重复序列号的数据。这也是TCP传输可靠性的保证之一

3)、超时重传

(1)、发送数据过程中为什么没有客户端没有收到服务端返回的ACK的数据包

发送方发送一部分数据后,都会等待接收方发送的ACK报文,但是这时候发送方没有收到ACK的数据包是怎么回事?

  • 数据在传输过程中由于网络原因等直接全体丢包,接收方根本没有接收到(发送服务端中途丢包)
  • 收方接收到了响应的数据,但是发送的ACK报文响应却由于网络原因丢包了 (服务端收到包,返回客户端丢包)

(2) 、重传机制

TCP在解决这个问题的时候引入了一个新的机制,叫做超时重传机制就是发送方在发送完数据后等待一个时间,时间到达没有接收到ACK报文,那么对刚才发送的数据进行重新发送

如果是刚才第一个原因,接收方收到二次重发的数据后,便进行ACK应答。

如果是刚才第二个原因,接收方发现接收的数据已存在(判断存在的根据就是序列号,所以上面说序列号还有去除重复数据的作用),那么直接丢弃,仍旧发送ACK应答

(3)、重传时间间隔

在Linux中(BSD Unix和Windows下也是这样)超时以500ms为一个单位进行控制,每次判定超时重发的超时时间都是500ms的整数倍。重发一次后,仍未响应,那么等待2*500ms的时间后,再次重传。等待4*500ms的时间继续重传。以一个指数的形式增长。累计到一定的重传次数,TCP就认为网络或者对端出现异常,强制关闭连接。
 

4)、连接管理

就是三次握手与四次挥手的过程,可以看我的这篇博客 TCP之三次握手和四次挥手过程

5)、流量控制

我们知道实现流量控制是基于滑动窗口来实现的,请看我的这篇滑动窗口的博客 TCP之滑动窗口

6)、拥塞控制

TCP传输的过程中,发送端开始发送数据的时候,如果刚开始就发送大量的数据,那么就可能造成一些问题。网络可能在开始的时候就很拥堵,如果给网络中在扔出大量数据,那么这个拥堵就会加剧。拥堵的加剧就会产生大量的丢包,就对大量的超时重传,严重影响传输。

所以TCP引入了慢启动的机制,在开始发送数据时,先发送少量的数据探路。探清当前的网络状态如何,再决定多大的速度进行传输。这时候就引入一个叫做拥塞窗口的概念。发送刚开始定义拥塞窗口为 1,每次收到ACK应答,拥塞窗口加 1。在发送数据之前,首先将拥塞窗口与接收端反馈的窗口大小比对,取较小的值作为实际发送的窗口。

拥塞窗口的增长是指数级别的慢启动的机制只是说明在开始的时候发送的少,发送的慢,但是增长的速度是非常快的。为了控制拥塞窗口的增长,不能使拥塞窗口单纯的加倍,设置一个拥塞窗口的阈值,当拥塞窗口大小超过阈值时,不能再按照指数来增长,而是线性的增长。在慢启动开始的时候,慢启动的阈值等于窗口的最大值,一旦造成网络拥塞,发生超时重传时,慢启动的阈值会为原来的一半(这里的原来指的是发生网络拥塞时拥塞窗口的大小),同时拥塞窗口重置为 1。

拥塞控制是TCP在传输时尽可能快的将数据传输,并且避免拥塞造成的一系列问题。是可靠性的保证,同时也是维护了传输的高效性。

部分类容参考了博客:https://blog.csdn.net/liuchenxia8/article/details/80428157

 

发布了1043 篇原创文章 · 获赞 630 · 访问量 286万+

猜你喜欢

转载自blog.csdn.net/u011068702/article/details/103942839