tcp三次握手,四次挥手的原因

根本原因

网络传输会丢包,需要ack包去保证传到了,而ack包依靠tcp重传机制的附带特性不需要第二个ack包去确认ack到达。

三次握手


tcp三次握手,四次挥手的原因

正常的tcp连接如上图所示

(1)客户端希望与服务端建立连接请求
(2)服务端告诉客户端同意建立连接请求
(3)客户端告诉服务端,收到了服务端的同意的信息

三个步骤存在的原因

步骤(1)缺失了,客户端连申请都不发送,服务端怎么知道你要连接
步骤(2)缺失了,服务端不告诉客户端同意,客户端怎么知道同不同意
前两个都是很好理解的,到了步骤(3)
步骤(3)存在的原因很明显只有一个,不知道(2)的包有没有到达,就是怕(2)丢包了,所以必须通过客户端使用ack包来反馈有没有丢,丢包是网络传送很有可能发生的事情,使用tcp时刻考虑这点就可以理解很多tcp的过程设计,而ack包就是用来确认没有丢包的手段。

问题又来了,为什么不是四次或者更多握手呢?第三次ack包也有可能会丢失,谁来保证ack包到达了,难道让对方也发一个ack包保证上一个ack包没有丢失,然后不断的循环下去吗?
ack实质上只是包的一个标志位,配合ack number值可以判断哪个包被对面收到了,在有数据发送的时候,这些信息本来就顺带保存在tcp报头中,但如果没有数据发送的话,这样一直发送ack包就是很浪费资源的事情
但tcp设置了重传定时器,对于每个包如果在规定的时间内没有收到ack包的话,那么有可能丢失了,就会按照一定的递增时间间隔发同样的包过去,而接收端发现一直收到同样的包则知道了ack包没有发到,则会再次发ack包过去,正是这个机制导致了ack包无须在通过另一个ack确定已经收到。




四次挥手


tcp三次握手,四次挥手的原因

断开连接分成两个部分
第一个部分是客户端不发数据了,要断开连接所以发送一个FIN包通知服务端,此时状态变为FIN_WAIT_1 (但此时还可以收数据,就是图中所说的半关闭状态)
第二个部分是服务端也不发数据了,发送一个FIN包给客户端

各个状态的含义
FIN_WAIT_1: 已经告诉服务端不发数据,只接受数据,未收到服务端确认
CLOSE_WAIT:收到客户端的FIN,客户端不发数据了,在等待我(服务端) 关闭
FIN_WAIT_2:服务端确认我不发数据,只接数据了

LAST_ACK:告诉客户端我也不发数据了,都关了
TIME_WAIT: 给服务端发个ack然后为了防止这个ack丢包,就等两个MSL(MSL最大生存时间,ACK最晚一个MSL还未到,服务端再次发一个FIN包告诉客户端ACK没到,最晚第二个MSL到来)
CLOSED:服务器关闭连接

最后,一个实例+总结


tcp三次握手,四次挥手的原因

如上图实例(整个过程没有数据传输),纯ack包是不占据序列也不需要ack去确认有没有丢包,而FIN(结束)和SYN(同步)包都占据一个序列(并且不会有数据在上面),FIN,SYN和数据包都需要ack包确认是否丢包,然后至今不解的是为什么FIN包中有ACK。