我们都知道tcp连接是三次握手,断开连接是四次挥手,那么为什么是三次握手?四次挥手?我想不少人存在疑惑,本文将分为三部分进行详细讲解。
三次握手
注意以下几个问题
- 为什么一次握手不行?
- 为什么两次握手不行?
- 为什么不选4次,偏偏就选3次?
- 连接建立时客户端和服务器如何进行信息交流?
-
建立连接的过程如下图:
-
问题一:为什么一次握手不行?
如果协议只有一次握手,那么在客户端第一次发送连接信号后,连接过程即结束,意思是客户端默认服务器已收到,并且进入连接状态。实际上该信号可能会丢失,所以客户端不可以默认服务器已收到,而且服务器即使收到了信号,也不可能百分百可以与客户端建立连接。因此一次握手不可行。
-
问题二:为什么两次握手不行?
理由其实同上,在服务器收到客户端发来的连接信号后,进行第二次握手,服务器发出响应信号,服务器也不可能默认客户端接收得到该信号,这时客户端跟服务器的状态仍然未知,因此两次握手也不可行。
-
问题三:为什么不选4次,偏偏就选3次?
我们来思考一下,前面的两次握手目的是什么?首先tcp连接是点对点的连接,也就是一对一的连接。那么前两次握手的目的在于客户端告诉服务器,我现在需要建立连接,而服务器再告诉客户端,我同意跟你建立连接。到这里,我们只需要保证这前两次握手都成功完成,连接就可以建立,第三次握手完成,就可以对前两次做保障。
而四次握手,甚至五次、六次确实都可以保障前两次正确完成,可三次能够完成的任务,却安排四次、五次,那消耗的资源更多,出现错误的可能性也更大。 -
问题四:连接建立时客户端和服务器如何进行信息交流?
tcp段结构如上图所示,在连接建立的过程中,主要用到了如下信号:
sequence number(序列号)、 acknowledgement number(确认序列号)、ACK(acknowledgement确认)、SYN(建立联机)
在连接的过程中,客户端和服务器都会随机选择一个初始序列号,并将自己的序列号告知对方。如初始第一个图所示,第一由客户端发送一个SYN信号给服务器,并携带客户端的初始序列号,表示客户端想要跟服务器建立连接。第二在服务器接收到SYN信号后,如果同意建立连接,则服务器会返回SYN+ACK信号,并携带服务器选择的初始序列号,表示同意建立连接。第三当客户端收到服务器的确认连接信号后,返回一个ACK确认信息,此时SYN标志位置为0,此后客户端确认建立连接,服务器收到ACK后确认连接建立。
四次挥手
注意以下几个问题
- 为什么连接是三次握手,而断开连接需要4次挥手,三次挥手不行吗??
- 断开连接时客户端和服务器如何进行信息交流?
-
断开连接的过程如下图:
-
问题一:为什么连接是三次握手,而断开连接需要4次挥手,三次挥手不行吗??
答案很明显是不可以的,在建立连接时,客户端和服务器之间一定不存在数据传输,连接都没建立,何来的数据传输呢?但是断开连接时不一定,当客户端想要断开连接时,客户端并不知道服务端是否还有数据需要传输。
我们设想如果是三次挥手,当客户端发送断开连接信号到达服务器时,服务器还有数据需要传输,此时,服务器如果发送确认信号,那么代表我同意断开连接,那剩下的数据该如何处理?如果服务器不发送确认信号,那么客户端如何知道服务器是否接收到了我的信号?那我需不需要重发?这些的问题的存在让三次挥手的可行性远不如4次挥手。 -
问题二:断开连接时客户端和服务器如何进行信息交流?
在断开连接的过程中,主要用到了如下信号:
sequence number(序列号)、 acknowledgement number(确认序列号)、ACK(acknowledgement确认)、FIN(finish结束)
在断开连接的过程中,如上图所示,第一由客户端发送一个FIN信号给服务器。表示我不再发送数据给你了,我要断开连接。第二服务器接收到该信号后,无论是否还有数据需要传输,都会马上返回一个ACK确认信息,表示好的,我知道了,但是我可能还有数据需要传输给你,客户端接收到确认信息后,进入半关闭状态,即不发送数据,但可以接收数据,等待服务器发来FIN信号。第三服务器发送FIN信号到客户端,含义与第一步相同。第四客户端收到FIN信号后,发送ACK确认信息给服务器,此后客户端等待一段时间,在这段时间内如果没有接收到来自服务器重复的FIN信号,完成断开连接,服务器收到ACK确认信息后,完成断开连接。
客户端和服务器的生命周期
客户端的生命周期图
服务器的生命周期图
以上两张图分别代表客户端和服务器从建立连接到断开连接的生命周期,每个节点代表了此时客户端或者服务器的状态,箭头表示状态发生变化,而箭头旁的事件代表发生状态变化的原因。