TCP的三次握手和四次挥手

三次握手

为什么是三次而不是两次或者四次? 因为两次太少,四次浪费,三次是保证双方相互明确对方能收能发的最低值。

理论上多少次握手这个可信的通道都是建立不起来的,但是通过三次握手至少可以确认它是可用的,往上加握手次数只是在提高这个可信的程度。

说是三次握手其实不够准确,因为其实就是两次握手两次确认,只是其中一方将握手和确认合并在了一块。或者说其实只是一次握手,毕竟是 three-way handshake,而不是 three handshakes ,有三个步骤的一次握手。

TCP 协议中大致分为五类报文:

  1. SYN 建立连接(Synchronize
  2. Data 数据传输
  3. FIN 断开连接(Finish
  4. Reset 重置连接
  5. ACK 确认连接(Acknowledgement

27894C0E-E440-4C22-8E32-E47D14735ED0

这图已经将三次握手的过程,画的非常清楚了,只需要知道一点,就是这个 seq 是什么,有什么用?

seq : 是由操作系统动态随机选取的一个 32 位长的序列号,该序列号是为了告诉对方哪些数据是合法的,因为之后的数据都会在此基础上增加。

TCP 握手,握的是什么,就是交换双方的数据原点的序列号,也是就是这个 seq 。

来看看,如果我们换成四次握手是怎么样的:

  1. A 发送 SYN + A’seq
  2. B 接收 A 的连接请求,记录 A’seq 到本地,命名 B 的 ACK 为 A’seq + 1
  3. B 发送 SYN + B’s seq
  4. A 接收到 B 的同步信号,记录 B’seq 到本地,命名 A 的 ACK 为 B’seq + 1

其中 2 和 3 可以合并为一个步骤。

那么如果 4 这个步骤中 A 的 ACK ,B 没有收到会怎么样呢?

A 不会重传这个 ACK ,而是 B 在没有收到 A 的 ACK 时,会不断的重传自己的 seq 直到接收的 A 的 ACK 为止。

如果换成两次握手又会是怎么样?

  1. A 发送 SYN + A’seq
  2. B 发送 SYN + B’seq + ACK

由于最后少了 A 的 ACK ,所以 B 不确定 A 是否真的收到了 B 的 seq ,可能 B 的 seq 发送失败了,那么这次握手其实是不成功的,但是双方都不清楚。

四次挥手

了解了三次握手之后再理解四次挥手就简单许多。

为什么挥手比握手多一次呢?多的这一次做了什么?

20170607205756255

看上图可以很直观的知道,关闭请求是客户端发出的,当客户端发出关闭请求时,服务端可能还有数据没有传输完成,所以会先发一个收到关闭请求的 ack ,等数据全部传输完成之后再发送 FIN,其它三步骤和三次握手基本一样。

这里有个比较有意思的东西,在客户端发送了最后的 ACK 包之后,会等待 2MSL ,这个 2MSL 是什么,为什么最后需要等待 2MSL 呢?

MSL(Maximum Segment Lifetime),报文最大生存时间,任何报文在网络上超过该时长都会被丢弃。

等待 2MSL 的目的就是担心最后一个 ACK 包对方没有收到,因为如果对方真的没有收到这个 ACK 就会重新发送之前的 FIN,那么此时就需要再次发送 ACK ,然后重置等待时间为 2MSL ,直到对方不发送 FIN 默认就是收到了 ACK 。