前言
前面我说到了,UDP通信的实现,但我们经常说UDP通信不可靠,是因为他只会接收和发送,并不会去验证对方收到没有,那么我们说TCP通信可靠,就是因为他会进行验证接收端是否能够接收和发送,并且只有在验证通过的情况下才会发送数据,并且会通过一些操作来保证数据发送的完整性。本小节主要介绍TCP通信过程中如何通过三次握手和四次挥手来保证数据的传输。
一、三次握手
TCP(Transmission Control Protocol)通信中,三次握手是指在客户端和服务器之间建立可靠连接时的三步过程。这一过程的目的是确保双方都能够准备好进行数据传输,并且能确认彼此的接收和发送能力。视频链接:屏幕录制 2024-09-10 221512-CSDN直播
TCP三次握手的详细过程
第一次握手:客户端发送SYN包
- 客户端向服务器发送一个SYN(Synchronize)标志位为1的TCP报文段,表示客户端想要发起连接,并请求同步序列号(Sequence Number)。
- 在这个阶段,客户端会生成一个初始序列号(ISN,Initial Sequence Number),并将这个序列号放入报文中。
- 报文格式:
SYN = 1, SEQ = x
(x
是客户端的初始序列号)第二次握手:服务器回复SYN-ACK包
- 服务器收到客户端的SYN报文后,理解到客户端想建立连接。于是,服务器也生成一个自己的初始序列号,并发送一个SYN-ACK(Acknowledgment)报文段回给客户端,表示接收到客户端的连接请求。
- 在这个SYN-ACK报文中:
- SYN = 1:表示服务器同意建立连接。
- ACK = 1:表示确认客户端发出的SYN。
- ACK序列号:
x + 1
,表示确认客户端的序列号x
。- 服务器同时也会发送自己的序列号
y
。- 报文格式:
SYN = 1, ACK = 1, SEQ = y, ACK = x + 1
第三次握手:客户端发送ACK包
- 客户端收到服务器的SYN-ACK报文后,确认服务器收到了自己的连接请求,接着客户端发送一个确认报文段(ACK = 1)给服务器,确认服务器的SYN和ACK。
- 在这个ACK报文中:
- ACK = 1,表示确认服务器的序列号。
- ACK序列号:
y + 1
,表示确认服务器的序列号y
。- 报文格式:
ACK = 1, SEQ = x + 1, ACK = y + 1
此时,双方都已经完成了三次握手,客户端和服务器之间的TCP连接已经建立,接下来可以开始数据传输。
我们可以这样理解:
客户端需要知道:客户端自己的接收和发送能力;服务器的接收和发送能力;
服务器需要知道:客户端的接收和发送能力;服务器自己的接收和发送能力;
第一次握手:客户端发送请求,服务器接收请求,这时,服务器知道自己有接收能力;其余能力没有。
第二次握手:服务器发送信号告诉客户端,自己知道了客户端的连接请求,等到信号传递到客户端之后,这时,客户端知道服务器有接收能力,发送能力;客户端也知道了自己有发送能力,和接收能力,但是服务器不知道客户端有没有接收能力。
第三次握手:客户端发送信号给服务器表示自己知道了服务器有发送和接收能力,等到服务器接收到信号以后,服务器知道了客户端收到了第二次握手发送的数据,这时,服务器知道客户端有接收能力;
到此:客户端知道自己有的接收和发送能力;服务器也知道的自己有接收和发送能力;
二、四次挥手
四次挥手是指在TCP(Transmission Control Protocol)通信中,客户端与服务器之间关闭连接的过程。与三次握手类似,四次挥手也是为了确保双方能够有序地终止连接。由于TCP是全双工通信协议,即通信双方都可以同时发送和接收数据,因此关闭连接时需要双方都同意停止发送和接收数据,整个过程需要四个步骤,称为“四次挥手”。
四次挥手的详细过程
第一次挥手:客户端发送FIN包
- 当客户端想要结束数据传输时,它会发送一个**FIN(Finish)**标志位为1的报文,告诉服务器它已经不再发送数据了,但仍然可以接收来自服务器的数据。
- 这时,客户端进入FIN_WAIT_1状态,等待服务器的响应。
- 报文格式:
FIN = 1, SEQ = x
(x
为当前的序列号)第二次挥手:服务器回复ACK包
- 服务器收到客户端的FIN报文后,回复一个ACK(Acknowledgment)报文,表示它收到了客户端的请求,但此时服务器可能仍然有数据要发送,因此不会立即关闭连接。
- 服务器发送的ACK报文中的确认号为
x + 1
,表示确认客户端的序列号x
。- 此时,客户端进入FIN_WAIT_2状态,继续等待服务器的FIN报文,而服务器进入CLOSE_WAIT状态,准备关闭连接。
- 报文格式:
ACK = 1, SEQ = y, ACK = x + 1
第三次挥手:服务器发送FIN包
- 当服务器处理完剩余的数据并准备好关闭连接时,它会发送一个FIN报文,通知客户端它也准备结束通信,不再发送数据了。
- 服务器此时进入LAST_ACK状态,等待客户端的最后确认。
- 报文格式:
FIN = 1, SEQ = y
(y
为服务器当前的序列号)第四次挥手:客户端回复ACK包
- 客户端收到服务器的FIN报文后,回复一个ACK报文,确认服务器已经关闭连接。
- 发送完ACK报文后,客户端进入TIME_WAIT状态,等待一定的时间(通常为2个最大段寿命时间,2MSL,Maximum Segment Lifetime),以确保服务器收到这个ACK报文后不会重发FIN报文。如果在此期间没有收到任何新数据包,客户端才正式关闭连接,进入CLOSED状态。
- 服务器收到客户端的ACK报文后,也进入CLOSED状态,连接彻底关闭。
- 报文格式:
ACK = 1, SEQ = x + 1, ACK = y + 1