Treasure / tcp协议

Created Thu, 16 Sep 2021 00:00:00 +0000
1389 Words

什么是 Tcp

三次握手

  1. tcp client发送连接请求报文,报文首部同步标记位 SYN=1 同时随机序列号 seq=x,此时 tcp client 进入 SYNC-SENT 状态的

  2. tcp server 若同意连接则确认报文为 ACK=1,SYN=1,ASK=x+1,seq=y 返回给客户端,并进入 SYNC_RCVD 状态

  3. tcp client 收到回复并确认 ACK 是否为1,seq 是否为 x+1,并返回报文 ACK=1,ASK=y+1,此时双方进入 ESTABLISHED 状态

四次挥手

  1. 主动方发送报文FIN=1,seq=last+1并进入FIN_WAIT_1,此时报文不能携带任何数据

  2. 被动方收到连接释放报文,并发送确认报文 ACK=1,ack=u+1,seq=v ,并进入 CLOSE_WAIT状态,但此时如果缓冲区存在未发送数据,那么需要继续发送(这也是 CLOSE_WAIT 持续的时长),主动方收到此条报文后进入 FIN_WAIT_2,因为还需要处理未发送数据

  3. 上一步执行完毕,被动方发送 FIN=1,ack=w+1,seq=u+1 并进入 LAST-ACK 状态,而主动方收到此条报文后进入 TIME_WAIT (2msl maximum segment life),之后才会进入 CLOSED

  4. 在主动方进入 CLOSED 之前,需要发送报文确认退出

2MSL

1MSL保证主动方最后的 ACK 能到达对端,1MSL 确保 ACK 重传

如何确保可靠性

  1. 三次握手,四次挥手确保连接和断开的可靠

  2. 记录了哪些数据被接受,哪些未接收,序列号保证了消息的顺序性

  3. ACK应答,超时重传,失序重传,丢弃重复数据,流量控制,拥塞控制

重传机制

RTT,RTO

Round-Trip Time 消息往返时间 Retransmission Timeout 超时重传

快速重传

不以时间为驱动,而是以接收方返回信息触发

滑动窗口

本质上是内核开辟了一个缓冲区,依据tcp头部的win(16bit) 来确认,其大小表示无需等待确认应答,可以发送或接收数据的最大值,在发送确认报文的时候同时告知对方

  1. 发送窗口

分为四段,已发送已确认,已发送未确认,未发送但可发送,未发送但不可发送

  1. 接收窗口

分为三段,已接收并确认,未接收但可以接收,未接收且不可接收

拥塞机制

拥塞控制是作用于网络的,防止过多的数据包注入到网络中,避免出现网络负载过大的情况。它的目标主要是最大化利用网络上瓶颈链路的带宽。它跟流量控制又有什么区别呢?流量控制是作用于接收者的,根据接收端的实际接收能力控制发送速度,防止分组丢失

发送方维护一个 cwnd 窗口,估算当前网络可以承载的数据量,它是动态的,只要没有出现阻塞就增大一些,若阻塞则减少一些

拥塞算法

  1. 慢启动

连接建立完成后,先探测网络的拥塞程度,如果未出现丢包,没收到一个ACK,cwnd+1(MSS),每一个RTT过后cwnd增加一倍,若出现丢包则减半

  1. 拥塞避免

当cwnd超过慢启动阈值ssthresh时,进入拥塞避免,一般是64kb,即cwnd不再增加

  1. 拥塞发生

当网络拥塞发生丢包时,存在两种情况: RTO超时重传,慢启动阈值减半,cwnd = 1,并重新进入慢启动。发送发收到3个重复的ACK时进入快速重传,cwnd=cwnd/2,ssthresh = cwnd,并进入快速恢复

  1. 快速恢复

cwnd = ssthresh +3 ,重传丢失的的数据包,如果再收到重复的ACK,则 cwnd+1,当收到新的ACK后(即恢复正常)cwnd=ssthresh,并重新进入拥塞避免

半连接

即tcp server 回复 ACK,SYN 后,这个连接被推入了SYN队列,即半连接队列,若 tcp client 确认并回复ACK后则会被推入Aceept队列,即全连接队列

预防 SYN FLOOD

伪造不存在ip,发送大量的SYN报文,导致服务器无法收到正确的ACK报文,以至于半连接队列满载

  1. SYN PROXY 代理真实服务器的半连接队列

  2. SYN COOKIE 服务器拦截原始SYN报文,这个太硬核

粘包和拆包

由于发送缓冲区的关系,以及读取缓冲区的关系,一般由业务层决定(固定长度,长度+消息,请求应答)