计算机网络–TCP三次握手

不管是前端,还是面各种后端,计算机网络的三次握手都是一个高频考点,常问的就是,介绍一下三次握手,然后很多情况下会加一个,为什么需要三次握手

我们先来考虑第二个问题

为什么需要三次握手

TCP作为一种可靠传输控制协议,其核心思想:既要保证数据可靠传输,又要提高传输的效率

下面的话来源于知乎上的一段高赞回答

在谢希仁《计算机网络》第四版中是这样讲”三次握手“的目的的:为了防止已经失效的连接请求报文段突然又传送到了服务端,因而产生错误”,这里只能算是表因,未涉及本质

根据TCP的协议RFC–RFC793TCP需要seq序列号来做可靠重传或接受,为了避免连接复用时无法分辨出seq是延迟还是旧链接的seq,因此需要三次握手来确定双方的ISN(初始seq序列号)

下面是对RFC的解读:

我们首先需要知道一点就是,TCP的可靠连接是靠seq来达成的

A fundamental notion in the design is that every octet of data sent over a TCP connection has a sequence number. Since every octet is sequenced, each of them can be acknowledged. The acknowledgment mechanism employed is cumulative so that an acknowledgment of sequence number X indicates that all octets up to but not including X have been received.

  • TCP涉及中一个基本设定就是,通过TCP连接发送的每一个包,都有一个seq num,而每一个包都是有序列号的,所以都能被确认收到这些包。确认机制是累计的,所以一个对seq num X的确认,意味着X序列号之前(但不包含X)的包都是已经被确认收到的

The protocol places no restriction on a particular connection being used over and over again. The problem that arises from this is -- "how does the TCP identify duplicate segments from previous incarnations of the connection?" This problem becomes apparent if the connection is being opened and closed in quick succession, or if the connection breaks with loss of memory and is then reestablished.

  • TCP协议是不限制一个特定的连接(两端socket一样)被重复使用的,所以这样就出现了一个问题:这条连接突然断开重连后,TCP怎么样识别之前旧链接重发的包?–这样就需要独一无二的ISN(初始序列号)机制

When new connections are created, an initial sequence number (ISN) generator is employed which selects a new 32 bit ISN. The generator is bound to a (possibly fictitious) 32 bit clock whose low order bit is incremented roughly every 4 microseconds. Thus, the ISN cycles approximately every 4.55 hours. Since we assume that segments will stay in the network no more than the Maximum Segment Lifetime (MSL) and that the MSL is less than 4.55 hours we can reasonably assume that ISN's will be unique.

  • 当一个新连接建立时,初始序列号(ISN)生成器会生成一个新的32位的ISN。这个生成器会用一个32位的时钟,差不多4 µs 增长一次,因此ISN大约会在4.55小时循环一次(2^32位的计数器,需要2 ^32*4 µs才能自增完,除以1小时共有多少µs便可算出2^32*4 /(1*60*60*1000*1000)=4.772185884)。而一个段在网络中并不会比最大分段寿命(MSL,默认两分钟)长,MSL比4.55小时要短,所以我们可以认为ISN会是唯一的

发送方与接收方都有自己的ISN用来做双方的互发通信,描述如下

1) A --> B SYN my sequence number is X

2) A <-- B ACK your sequence number is X

3) A <-- B SYN my sequence number is Y

4) A --> B ACK your sequence number is Y

  • 可以看到2,3都是B发给A,所以合并在一起,称之为“三次握手”

A three way handshake is necessary because sequence numbers are not tied to a global clock in the network, and TCPs may have different mechanisms for picking the ISN's. The receiver of the first SYN has no way of knowing whether the segment was an old delayed one or not, unless it remembers the last sequence number used on the connection (which is not always possible), and so it must ask the sender to verify this SYN. The three way handshake and the advantages of a clock-driven scheme are discussed in [3].

  • 三次握手是必须的,因为seq没有绑定到整个网络的全局时钟(如果绑定了,整个网络使用同一个时钟,就可以确定这个包是不是延迟到的)以及TCPs可能有不同的机制来选择ISN。接收方接到第一个SYN时,没办法知道这个SYN是否是延迟了很久,除非他有办法知道在这条连接中,最后接收到的那个seq
  • 简单来说就是:一个seq过来了,跟记住的seq不一样,我怎么早知道他是上一个延迟的,还是上上条延迟的呢,所以一定要跟发送方确认SYN。

是否两次握手就可以呢

1) A --> B SYN my sequence number is X

2) A <-- B ACK your sequence number is X SYN my sequence number is Y `

  • 这里可以看到A与B,就A的序号问题达成一致位X,但是B无法知道A是否以及接收到了自己的同步信号,如果这个同步信号丢失,A与B就B的ISN就无法达成一致
  • SYN同步标志位为一个字节的编号,是数据,所以TCP设计原则,对数据必须要有确认,所以A必须要给B一个确认

如果A给B的确认丢了,该怎么办

  • A不会超时重传这个ACK,(因为ACK不包含数据,TCP不会为没有数据的ACK重传)
  • 所以B没有收到A的ACK,会超时重传自己的SYN信号,直到收到A的ACK为止

三次握手过程

1
2
3
4
5
6
7
8
9
10
11
TCP A                                                TCP B
1 CLOSED LISTEN
2 SYN-SENT --> <SEQ=100><CTL=SYN> --> SYN-RECEIVED
3 ESTABLISHED<--<SEQ=300><ACK=101><CTL=SYN,ACK> <--SYN-RECEIVED
4 ESTABLISHED --> <SEQ=101><ACK=301><CTL=ACK> --> ESTABLISHED
5 ESTABLISHED --> <SEQ=101><ACK=301><CTL=ACK><DATA> --> ESTABLISHED

Basic 3-Way Handshake for Connection Synchronization

作者:知乎用户
链接:https://www.zhihu.com/question/24853633/answer/573627478