TCP(上)

110 阅读6分钟

TCP三次握手与四次挥手

TCP基本认识

image.png

image.png

TCP连接建立

image.png

image.png

image.png

image.png

第三次握手是可以携带数据的。

TCP建立连接时,三次握手 能防止历史连接的建立,能减少双方不必要的资源开销,能帮助双方同步初始化序列号。

不使用 两次握手 的原因:

  • 两次握手:无法防止历史连接的建立,会造成双方资源的浪费,也无法可靠的同步双方序列号。

为什么TCP层还需要MSS

image.png

若TCP被MTU分片,仅第一个分片有TCP头部,接收方IP层只有重组了这些分片才会认为是一个TCP报文,交付给TCP层;因此,若丢失了一个分片,则需要超时重传整个TCP报文;

若TCP报文被MSS分片,那么每个分片都是具有TCP头部的TCP报文。


什么SYN攻击?如何避免SYN攻击?

攻击者短时间伪造不同IP地址的SYN报文,服务端发送ACK+SYN报文后,没有得到ACK应答; 久而久之就会占满服务端的SYN接受队列(半连接队列)。

避免SYN攻击方式一

修改Linux内核:

  • 当网卡接收数据包的速度大于内核处理速度时,会有一个队列保存这些数据包;控制该队列的最大值。
  • SYN_RCVD状态连接的最大个数;
  • 超出处理能时,对新的SYN直接回报RST

避免SYN攻击方式二

image.png

image.png

image.png

image.png

TCP连接断开

image.png

为什么TIME_WAIT等于2MSL?

MSL是报文最大生存时间。 这其实相当于至少允许报文丢失一次;若ACK在1个MSL内丢失;这样被动方重发的FIN会在第2个MSL内到达。

2MSL是从客户端接收到ACK后发送ACK开始计时的。 若在TIME_WAIT内客户端的ACK没有传输到服务端,客户端又接收到了服务端重发的FIN报文,2MSL时间重新计时。

为什么需要TIME_WAIT
  1. 防止旧连接的数据包

image.png

  1. 保证连接正确关闭

image.png

TIME_WAIT过多的危害?
  1. 内存资源占用

  2. 端口资源占用

  • 客户端:一个TCP连接至少消耗一个本地端口
  • 服务端:把连接扔给处理线程,所以理论上端口可以继续监听;但是线程池有限。
如何优化TIME_WAIT
  1. 复用处于TIME-WAIT的socket为新的连接所用;
  2. 当TIME-WAIT连接数超过一定值后,将后面的TIME-WAIT连接重置
  3. 立刻发送RST标志给对端,该TCP连接将跳过四次挥手,也就跳过了TIME-WAIT。(但十分危险)
如果已经建立连接,客户端忽然出现故障?

保活机制

一定时间段内,若没有任何连接相关的活动;每隔一个时间间隔,发送一个探测报文;若连续几个探测报文没有得到响应,则认为该连接死亡。

若开启了TCP保活:

  • 对端正常工作:对端正常响应,TCP保活时间被重置。
  • 对端崩溃并重启:对端响应RST报文,TCP连接被重置。
  • 对端没有响应:该连接已死亡。

Socket编程

image.png

服务端调用 accept 时,连接成功了会返回一个已完成连接的socket,后续用来传输数据; 所以,监听socket和已完成连接socket是两个socket。

image.png

image.png

image.png

TCP重传、滑动窗口、流量控制、拥塞控制

重传机制

超时重传

image.png

RTT是数据包的往返时间。RTO是超时重传时间。

image.png

image.png

实际上,RTT是经常变化的; 所以,RTO应该是一个动态变化的值。 估计RTO,通常需要采样:

  • 采样RTT并加权平均,算出一个平滑RTT的值
  • 采样RTT的波动范围

超时重发的数据再次超时,TCP的策略是超时间隔加倍。

快速重传

image.png

问题:是重传Seq2?还是重传Seq2、Seq3、Seq4、Seq5呢?

SACK

在TCP头部 选项 字段加一个SACK的东西,将缓存的地图发给发送方。

image.png

D-SACK

使用SACK来告诉发送方有哪些数据被重复接收。

ACK丢包

image.png

网络延时

image.png

滑动窗口

累计确认/累计应答

image.png

窗口大小由哪一方决定?

TCP头有一个字段:Window。

这个字段是接收方告诉发送方自己还有多少缓冲区接收数据。于是,发送方可以根据接收方的处理能力发送数据。

所以,窗口的大小是由接收方的窗口大小来决定。

发送窗口

image.png

image.png

image.png

image.png

接收窗口

image.png

接收窗口的大小约等于发送窗口的大小。 因为新的接收窗口大小是通过TCP报文的Windows字段告诉发送方的。 这个传输过程存在时延。

流量控制

image.png

操作系统缓冲区与滑动窗口的关系

上一张图,我们假定了发送窗口和接收窗口是不变的。

事实上,操作系统的缓冲区会影响发送和接收窗口。

image.png

发生了窗口关闭。

image.png

为了防止这种情况发生(窗口大小出现负值),TCP规定只能先收缩窗口,过段时间再减少缓存。

窗口关闭

窗口关闭的潜在危险

image.png

TCP是如何解决窗口关闭时潜在的死锁现象呢?

image.png

  • 若接收窗口仍为0,发送方重启计时器。

窗口探测的次数一般为3次。若3次之后接收窗口仍为0,有的TCP实现就会发RST来中断连接。

糊涂窗口综合症

image.png

如果接收方腾出几个字节并告诉发送方,发送方也会义无反顾 发送这几个字节。TCP+IP头都有40字节,开销过大。

解决办法:

  • 让接收方不通知小窗口
  • 让发送方避免发送小数据

让接收方不通知小窗口

窗口大小 小于 min(MSS,缓存空间/2),即向发送方告知窗口为0;

让发送方避免发送小数据

使用Nagle算法,发送数据要满足以下两条中的一条:

  • 当窗口大小或数据大小 >= MSS
  • 收到之前发送数据的ACK包

拥塞控制

避免发送方的数据填满整个网络。

拥塞窗口cwnd:根据网络的拥塞程度动态变化。

  • 网络中没有出现拥塞,cwnd增大;
  • 网络中出现了拥塞,cwnd减少;

只要发生了超时重传,就认为网络出现了拥塞。

慢启动

image.png

拥塞避免

image.png

拥塞发生

拥塞发生,也就是会发生数据包重传:

  • 超时重传
  • 快速重传

发生超时重传的拥塞发生算法

image.png

太激进,会造成网络卡顿。

快速恢复

快速重传和快速恢复算法一般同时使用。

image.png