TCP协议:三次握手和四次挥手(完整详细讲解)
TCP协议的三次握手
TCP(传输控制协议,传输控制协议)是一种面向连接的、可靠的、基于字节流的通信协议,数据在传输前要建立立连接,传输完毕后还要断开连接。
客户端在收发数据前要使用connect()函数与服务器建立连接。建立连接的目的是保护IP地址、端口、物理链路等正确无误,为数据的传输开辟通道。
TCP建立连接时要传输三个数据包,俗称三次握手(Three-wayHandshaking)。可以很形象的比如为下面的对话:
[Shake1]套接字A:“你好,套接字B,我这里有数据要传送给你,建立连接吧。”
[Shake2]套接字B:“好的,我这边已准备就绪。”
[Shake3]套接字A:“谢谢你受理我的请求。”
TCP连接建立采用三次握手机制,确保双方通信能力正常。客户端主动发起连接请求,服务器被动响应。
第一次握手:客户端发送SYN=1报文,随机生成初始序列号seq=x,进入SYN_SENT状态。
第二次握手:服务器收到SYN报文后,发送SYN=1和ACK=1的报文,确认号ack=x+1,同时随机生成自己的初始序列号seq=y,进入SYN_RCVD状态。
第三次握手:客户端收到SYN+ACK报文后,发送ACK=1报文,确认号ack=y+1,序列号seq=x+1。双方进入ESTABLISHED状态,连接建立完成。

TCP的数据传输的过程

注意:最后加1是为了告诉对方要传递的Seq号。
Ack号=Seq号+传递的字节数+1
三次握手的必要性
防止历史重复连接初始化造成的资源浪费。通过三次交互确认双方的收发能力正常。同步双方的初始序列号,为后续可靠传输奠定基础。
TCP协议的四次挥手
TCP连接释放采用四次挥手机制,确保数据完整传输并安全关闭连接。任何一方均可主动发起关闭请求。
建立连接需要三次握手,彼此都要回一个ACK确认包,而断开连接需要四次挥手,可以形象的比喻为下面的对话:
[Shake 1] 套接字A:“任务处理完毕,我希望断开连接。”
[Shake 2] 套接字B:“哦,是吗?请稍等,我准备一下。”
等待片刻后……
[Shake 3] 套接字B:“我准备好了,可以断开连接了。”
[Shake 4] 套接字A:“好的,谢谢合作。”
第一次挥手:主动关闭方发送FIN=1报文,序列号seq=u,进入FIN_WAIT_1状态。
第二次挥手:被动关闭方收到FIN报文后,发送ACK=1报文,确认号ack=u+1,进入CLOSE_WAIT状态。主动方收到后进入FIN_WAIT_2状态。
第三次挥手:被动关闭方完成数据发送后,发送FIN=1报文,序列号seq=v,确认号ack=u+1,进入LAST_ACK状态。
第四次挥手:主动关闭方收到FIN报文后,发送ACK=1报文,确认号ack=v+1,进入TIME_WAIT状态。被动方收到后立即关闭连接,主动方等待2MSL后关闭。

建立连接后,客户端和服务器都处于ESTABLISED状态。这时,客户端发起断开连接的请求:
(1)客户端调用close()函数后,向服务器发送FIN数据包,进入FIN_WAIT_1状态。FIN是Finish的缩写,表示完成任务需要断开连接。
(2)服务器收到数据包后,检测到设置的FIN标志位,知道要断开连接,于是向客户端发送“确认包”,进入CLOSE_WAIT状态。
注意:服务器收到请求后并不是立即断开连接,而是先向客户端发送“确认包”,告诉它我知道了,我需要准备一下才能断开连接。
(3)客户端收到“确认包”后进入FIN_WAIT_2状态,等待服务器准备完毕后再次发送数据包。
(4)等待片刻后,服务器准备完毕,可以断开连接,于是再主动向客户端发送FIN包,告诉它我准备好了,断开连接吧,然后进入LAST_ACK状态。
(5)客户端收到服务器的FIN包后,再向服务器发送ACK包,告诉它你断开吧。然后进去TIME_WAIT状态。
(6)服务器收到客户端的ACK包后,就断开连接,关闭套接字,进入CLOSED状态。
四次挥手的原因
TCP是全双工协议,每个方向需要单独关闭。FIN报文只表示该方向不再发送数据,但可能还需要接收对方的数据。TIME_WAIT状态确保最后一个ACK能到达对端,同时让网络中残留的报文失效。
关键状态说明
SYN_SENT:客户端发送SYN后等待确认的状态。
SYN_RCVD:服务器收到SYN后发送SYN+ACK的状态。
ESTABLISHED:连接建立完成后的正常工作状态。
FIN_WAIT_1:主动关闭方首次发送FIN后的状态。
FIN_WAIT_2:主动关闭方收到第一次ACK后的状态。
TIME_WAIT:确保连接彻底关闭前的等待状态。
CLOSE_WAIT:被动关闭方收到FIN后的中间状态。
LAST_ACK:被动关闭方发送FIN后的最终等待状态。
思考:为什么是三次握手而不是两次握手?
为了实现可靠的数据传输,TCP协议的通信双方都必须维护一个序列号,以标识发送出去的数据包中,哪些是已经被对方收到的。三次握手的过程即是通信双方相互告知序列号起始值,并确认对方已经收到了序列号起始值的必经步骤。
如果只是两次握手,至多只有连接发起方的起始序列号能被确认,另一方选择的序列号则得不到确认。
(仅自己的理解,觉得有帮助可以一键三连,有其他想看的内容也可以私聊)
更多推荐



所有评论(0)