TCP(传输控制协议)使用三次握手(3WHS)来建立一个可靠的连接,并使用四次挥手(4WHS)来终止连接。以下是每个步骤的详细解释:
三次握手(3WHS)建立连接:
-
SYN(同步序列编号):
- 客户端选择一个初始序列号x,并发送一个带有SYN标志的TCP段给服务器,请求建立连接。此时,TCP段的序列号字段设置为x。
-
SYN-ACK(同步-确认):
- 服务器收到客户端的SYN段后,如果同意建立连接,则会发送一个SYN-ACK段作为响应。服务器选择自己的初始序列号y,并在ACK(确认)字段中确认客户端的序列号x+1(期望接收到的第一个字节的序列号)。同时,SYN标志位也被设置。
-
ACK(确认):
- 客户端收到服务器的SYN-ACK段后,发送一个带有ACK标志的TCP段给服务器,确认服务器的初始序列号。客户端在ACK字段中填入y+1。
完成这三个步骤后,TCP连接就成功建立,客户端和服务器可以开始发送数据。
为什么需要三次握手:
- 防止已失效的连接请求报文段突然传到服务器,因而产生错误 :如果使用两次握手,服务器端收到一个旧的连接请求并响应,可能会导致服务器错误地建立一个新连接。
例子: - 允许双方确认彼此的初始序列号:三次握手确保了客户端和服务器都能够确认对方的接收能力和发送能力。
四次挥手(4WHS)终止连接:
-
FIN(结束):
- 当一方完成数据传输并希望关闭连接时,它发送一个带有FIN标志的TCP段,表示已经没有数据要发送了。
-
ACK(确认):
- 对方收到FIN段后,发送一个ACK段确认这个FIN。
-
FIN(结束):
- 对方完成数据传输后,也发送一个带有FIN标志的TCP段。
-
ACK(确认):
- 最初发送FIN的一方收到这个FIN段后,发送最后一个ACK段确认。
完成这四个步骤后,TCP连接被关闭。
为什么需要四次挥手:
- TCP连接是全双工的:意味着数据可以在两个方向上独立传输。因此,每个方向上的连接都需要单独关闭。
- 确保数据传输完成:四次挥手允许一方在关闭自己的发送部分后,仍然接收来自对方的剩余数据。
上述为什么要三次握手第一个原因的理解
为什么TCP连接建立需要三次握手,而两次握手可能不足以防止"已失效的连接请求"的问题。
假设场景:
假设客户端A想要与服务器B建立TCP连接,但是客户端A发送的第一个连接请求(SYN)在网络中延迟了,没有立即到达服务器B。
第一次握手(SYN):
- 客户端A发送一个SYN报文(假设序列号为1000)给服务器B,请求建立连接。
网络延迟:
- 这个SYN报文在网络中延迟,没有立即到达服务器B。
第二次握手(SYN+ACK,如果是两次握手):
- 假设我们只使用两次握手,客户端A在发送第一个SYN报文后,由于没有收到响应,会重新发送另一个SYN报文(假设序列号为2000)。
第三次握手(ACK,如果是两次握手):
- 服务器B最终收到了第二个SYN报文(序列号2000),并发送了一个SYN+ACK报文作为响应,同意建立连接。
延迟的报文到达:
- 此时,客户端A收到了服务器B的SYN+ACK报文,并发送了一个ACK报文确认,完成了两次握手过程。但是,之前延迟的第一个SYN报文(序列号1000)现在终于到达了服务器B。
问题出现:
- 如果服务器B在两次握手后没有收到客户端A的最终ACK确认,它可能会认为连接没有成功建立。因此,当服务器B收到延迟的SYN报文(序列号1000)时,它可能会错误地认为客户端A又发送了一个新的连接请求,并尝试重新建立一个新的连接。
三次握手的作用:
- 通过三次握手,即使客户端A的第一个SYN报文(序列号1000)延迟到达,服务器B也不会错误地建立一个新的连接。这是因为:
- 服务器B在收到第一个SYN(1000)后,会发送一个SYN+ACK(期望收到1000+1=1001),等待客户端的确认。
- 客户端A收到这个SYN+ACK后,会发送一个ACK(确认1001),但由于客户端A实际上发送的是序列号2000,所以这个ACK不匹配服务器B的期望。
- 服务器B收到不匹配的ACK后,会知道这不是对它发出的SYN+ACK的响应,因此不会错误地建立一个新的连接。
通过这个例子,你可以看到三次握手如何确保即使在网络延迟或重传的情况下,连接的建立也是可靠和有序的。它防止了因为旧的或延迟的连接请求而导致的不必要的连接建立,确保了服务器不会对已经失效或过时的连接请求做出响应。