背景知识

TCP是一个高可靠的主机到主机之间的通讯协议,这些主机位于分组交换网络(基于IP协议)中,也可能位于由这些网络组成的通讯系统中。TCP需要在不可靠的网络通讯系统中提供可靠的服务必须满足一系列基本实现,其中包括可靠性和多路复用。

为了实现可靠性,TCP连接发送的每个字节都有一个序列号。因为每个字节都编号了,所以可以对每个字节进行确认。

为了实现多路复用,TCP提供了一系列端口,主机地址加上端口号称为socket。TCP协议没有限制同一个TCP连接的重复使用。一个连接由一对socket唯一确定。

使用三次握手的充分性

如果一条连接突然断开重连后,TCP 如何识别旧连接发送的包?为了避免混乱,我们要避免当前连接正在使用的序列号与旧连接发送的且仍在网络中传输的数据包的序列号相同。并且要在TCP协议无法记住以前的序列号的前提下实现这个功能(因为TCP可能崩溃并忘记之前的序列号)。

为了实现上述功能,可以使用ISN生成器。当一个新连接建立时,初始序列号( initial sequence number ISN)生成器会生成一个新的32位的 ISN。ISN生成器生成的初始序列号是唯一的。

每一个连接都有一个接收序列号和发送序列号。发送初始序列号由发送数据的TCP实体选择,接收序列号是在连接建立时确定的。

连接建立时,两端必须要同步对方的初始序列号。双方通过同步带有SYN标志和初始序列号的数据段来实现。所以为了实现上述目的,一般需要一个初始化序列号选择器并且需要一些握手机制来同步初始化序列号。

同步机制需要发送自己的初始化序列号给对方,并且接收对方发送过来的确认信息。连接的两端必须接收对方发送过来的初始序列号并且发回确认信息。

A --> B  SYN my sequence number is X
A <-- B  ACK your sequence number is X
A <-- B  SYN my sequence number is Y
A --> B  ACK your sequence number is Y

因为第二步和第三步可以合并成一步,所以一般称为三次握手 the three way (or three message) handshake。

因为序列号并没有使用一个网络里的全局时钟来进行同步,而且不同 TCP实体会使用不同的机制来选择初始序列号。当一端接收到一个SYN连接请求时,无法确定这个连接请求是不是之前被网络延迟的连接请求(如果是之前的连接请求,应该拒绝连接),所必须向另一端确认这个序列号。所以三次握手是必须的。

使用三次握手的必要性

三次握手可以确保过期的连接请求即使重新送到了接收端也会被接收端抛弃。因为接收端每次接收到连接请求都会向发送方进行确认,而因为不会出现相同的序列号,所以接收端接受的这个过期的连接请求的序列号一定与发送方的初始序列号不同,所以这个过期的连接请求一定会被拒绝。

三次握手可以确保两端进行可靠的数据传输。因为连接时两端都知道对方的初始序列号,所以接下来的传输过程双方对整个传输过程的序列号都是完全掌握的。

参考资料:

https://datatracker.ietf.org/doc/html/rfc793

https://book.douban.com/subject/10510747/(6.2.2节)