为什么要三次握手:
The principle reason for the three-way handshake is to prevent old
duplicate connection initiations from causing confusion. To deal with
this, a special control message, reset, has been devised. If the
receiving TCP is in a non-synchronized state (i.e., SYN-SENT,
SYN-RECEIVED), it returns to LISTEN on receiving an acceptable reset.
If the TCP is in one of the synchronized states (ESTABLISHED,
FIN-WAIT-1, FIN-WAIT-2, CLOSE-WAIT, CLOSING, LAST-ACK, TIME-WAIT), it
aborts the connection and informs its user. We discuss this latter
case under "half-open" connections below.
TCP A TCP B
1. CLOSED LISTEN
2. SYN-SENT --> <SEQ=100><CTL=SYN> ...
3. (duplicate) ... <SEQ=90><CTL=SYN> --> SYN-RECEIVED
4. SYN-SENT <-- <SEQ=300><ACK=91><CTL=SYN,ACK> <-- SYN-RECEIVED
5. SYN-SENT --> <SEQ=91><CTL=RST> --> LISTEN
6. ... <SEQ=100><CTL=SYN> --> SYN-RECEIVED
7. SYN-SENT <-- <SEQ=400><ACK=101><CTL=SYN,ACK> <-- SYN-RECEIVED
8. ESTABLISHED --> <SEQ=101><ACK=401><CTL=ACK> --> ESTABLISHED
Recovery from Old Duplicate SYN
Figure 9.
这段文字是rfc793对为什么要三次握手的说明,大概意思是告诉你主要原因是为了防止旧的复用连接的初始话导致问题,以及当发生这种问题时,TCP的处理策略。ps(若复用连接的数据报在新建连接的数据包之后传输过来,则服务机不会对复用连接的数据包进行确认)
我自己的理解是为了同步连接双方的序列号和确认号,而同步连接双方的序列号和确认号的目的是为了防止已经失效的连接请求报文段突然又传到服务端,因而产生错误。
即可能会出现这样的情况,客户机已经建立了一条有效的连接,而之前因为某种原因失效的连接的数据包传输到了服务机,此时要如何辨别它是否是新建连接的数据包,由于TCP建立的连接ISN(初始序列号)是某种意义上是唯一的,所以假如我们服务机发送一个SYN ACK报文段,服务机发送的确认号和客户机的序列号对上的话,则可以保证数据包是新建连接的数据,但是此时如果我们客户机虽然知道这不是我想要的东西,服务机却是完全是毫不知情的,所以客户机对此要做出响应,避免服务机认为连接已经建立,空等,浪费资源。因此,三次握手是最少的保证(这也是为什么不两次握手和四次握手的原因,两次握手无法达到我们的目的,四次握手又无法提高连接可靠性,显得多余)。
为什么三次握手不带数据:首先第一点,这会降低连接效率,第二点,若三次握手带数据(两次连接的数据不一样大)的话,可能会导致新旧连接响应的确认号一样,从而无法分辨新旧连接的数据,这也是使用全局时钟为什么可以不握手的原因。