0%

TCP的三握四挥

文章 https://zhuanlan.zhihu.com/p/472361432 的学习笔记

TCP是面向连接的、可靠的、基于字节流的传输层通信协议

面向连接:只能一对一,不能一对多

TCP的连接是通过四元组唯一确认的:源IP、目标IP、源端口、目标端口

TCP和UDP的区别

TCP UDP
1 可靠 不可靠(丢包、乱序)
2 需要建立连接 不需要连接,即刻传输数据
3 一对一 一对多
4.有无拥塞控制和流量控制
5.头部长度开销 20字节(若有“选项“字段则会更长) 8字节
6.传输方式 流式传输 分包发送

TCP的目的是在不可靠的信道上建立可靠的连接

三次握手

.image-20220613154819476

.image-20220314112323551

.image-20220314112512144

.image-20220314112630756

.image-20220314112808974

注意,只有第三次握手可以携带应用层数据

为什么是三次握手而不是两次握手?

  1. 避免旧连接初始化造成混乱(主要原因)

.image-20220314132036207

网络拥堵时,旧连接可能未抵达,第三次握手用于确认是否是旧连接,如果是则发送RST报文,而两次握手做不到

  1. 三次握手确认了C/S双方都能同步序列号(Ack=Seq+1),而两次握手只能确认服务器同步无误

序列号能够保证数据不重复,不丢弃,按序传输

  1. 如果是两次握手,服务器收到SYN后只能直接分配资源建立连接,如果多个SYN阻塞在网络中,服务器会创建多个无效连接,造成资源浪费

四次挥手

连接断开后,服务器的资源得到释放

.image-20220314134918564

第一次挥手:我没有话要说了,但我还能继续听你说

第二次挥手:好的我知道了,我还有一些要说的话

第三次挥手:我现在也没有话要说了

第四次挥手:好的

为什么是四次挥手而不是三次挥手?

因为FIN+ACK是分开的,而握手的时候SYN+ACK是合在一起的

为什么要TIME_WAIT并且是2MSL?

MSL(Maximum Segment Lifetime,报文最大生存时间),Linux默认为30s,对应于IP中的TTL字段

  • 设置TIME_WAIT是为了保证最后的ACK能够到达服务器,使其正常关闭

    因为如果ACK没有到达服务器,服务器会超时重传FIN,而如果客户端此时关闭,服务器会一直处于LAST_ACK状态

  • 经过2MSL的时间,足够让两个方向的旧数据包都被丢弃,使得信道内的数据包都是新连接产生的