1. TCP三次握手的理解
首先我们需要了解什么是 SYN ,什么是 ACK。
SYN :他其实就是客户端和服务器端建立连接的一个握手信号,当客户端与服务器端建立正常的TCP网络连接的时候,客户端就会发送一个握手信号,也就是SYN。
ACK :这是一个确认字符,表示在数据通信中,接收方(接收到SYN信号的一方)发送给发送方(这里的发送方指的是发送SYN握手信号的那一方)的一个传输类控制符,表明已经确认接收无误。在正常的TCP网络连接中,如果接收方成功接收到数据,那么会回复一个 ACK信号给发送方。
第一次握手 :也就是图中的C ----SYN----> S 的这个过程,首先作为客户端,他发起请求连接服务器端,就会产生一个握手信号SYN,当发送到服务器端时,第一次握手结束。能够得到以下的信息:
- S他自己可以接收到C发来的信息
- C并不知道自己的信息发送到S那里没有
第二次握手 :也就是图中的S ----SYN+ACK----> C 的过程,作为服务器端,他接收到了SYN后,为了表示我能够接收到你发送过来的信息,我就要表个态,告诉你我接受到了信息,于是我就在SYN的基础上加一个ACK信号返回给客户端,当客户端接收到时,第二次握手结束。能够得到以下信息:
- C能够确认我自己之前发送的信息到达了你那里
- 并且C能够接受到S发送过来的信息 (这里就是为什么服务器返回的信息中要带着SYN回来的原因,只有带着它回来,才能在客户端验证自己之前发送的信息成功到了服务器端)
- 但是此时的S也并不知道自己的信息成功发出去没有
第三次握手 :也就是图中的 C ----ACK----> S的过程,为什么这一次握手不需要发送SYN了呢,是因为前面已经验证了自己的信息已经能够成功发送过去了,就没必要发送SYN了,这一次的握手的目的是为了让服务器端知道自己发送过去的ACK是成功的。所以只需要发送之前收到的ACK即可。当服务器端收到ACK之后,那么三次握手完成,能够建立起连接了。能够得到的信息是:
- S能够确认之前发送的信息发送成功了
- 可以建立通信了
看完这些,你应该能够知道为什么TCP网络连接只需要三次握手,而不是其他。如果你还不是很清楚,我用一个其他的例子引出这个概念。
假设两个人A和B分别在一个密闭的空间中,单单只从他们之间说的文字来判断问题,不考虑直接通过声音辨别是谁的情况下,如果这两个人要确认对方是谁,则需要进行以下步骤来确认。
A说:你好,我叫小A (小A这个名字就是SYN) --------> (B心里想:噢,原来你是小A啊。但是此时的A并不知道自己说的话发送到对方那里没。)
B说:小A你好,我叫小B(小A名字为SYN,小B名字为ACK) -------> (A心里想:噢,原来你是小B啊。同时他听到对方说的话中有自己的名字,这就证明了自己之前发送的信息已经成功到达了他耳边,但是此时的B并不知道自己回复的信息是否成功到了A那里。)
A说:小B你也好啊(小B为ACK) --------> (B心里想:ok我知道你收到我之前发送的消息了)
这样一来是不是就算是能够确认双方可以正常通信了。这也是最少的通信步骤了,你还能想象到能够用更少的步骤来完成通信吗,至少在目前为止是还不能的。这也就为什么只需要三次握手而不是其他。
2. TCP四次挥手的理解
首先我们要知道,什么是FIN。
FIN :表示发出一个结束信息,在TCP/IP的断开连接的时候,需要通过FIN信号来确认是否结束连接。
第一次挥手 :当C的请求都发完之后,C会发送一个FIN表示停止发送请求,但是此时还可以接收响应的数据,此时能够得到以下信息:
- C停止了发送请求,但是还可以接收数据
- S收到了C发送过来的停止连接信号
- C并不知道自己的结束连接信号发送过去没
第二次挥手 :当S接收到FIN信号之后,表示收到了C的结束连接信号,则需要先发送一个确认信号告诉C,我已经收到了你发送的结束信号,此时能够得到以下信息:
- C收到了S发送过来的确认信息收到的信号,表示之前自己发送的FIN无误
- C此时还有可能在接收S发送过来的响应数据
- S此时可能还在处理还没处理完全的请求
- S并不知道自己的信息是否传输到C那里
第三次挥手 :等到S全部处理完C发送过来的数据之后,表示自己可以开始关闭连接了,于是就会发送一个FIN给C,此时能够得到以下信息:
- C收到了S的结束连接信号,此时表示我已经接收了所有响应的数据了
- S并不知道自己的信息发送到C那里没
第四次挥手 :因为C已经得到了所有的响应数据了,那么我要还要告诉S我已经关闭了接受的功能了,当S收到信号时,此时能够得到以下信息:
- S知道了C已经关闭了接收信息的功能了,连接结束
为什么第二次和第三次不会同时发送?
这是因为当S收到FIN之后,只说明了C停止了发送,但是S并不一定就全部处理完了这些数据,可能还有一部分数据还在传输给S的过程中,因此只能先告诉C我收到了你的FIN信号,等到我S的全部数据都处理完并返回之后,S就能发送FIN信号表示我也已经发起关闭了。当然发起关闭就代表着我响应的数据已经发送出去了。C收到我发送的FIN信号就表示我已经全部接收到了响应的数据。