第三次握手为什么没有序列号_TCP为什么需要三次握手而不是两次?

面试的时候遇到一个问题:TCP为什么需要三次握手而不是两次?

073f5f8fa4d00246e81ee6b04bbdb68f.png

网上对此问题的回答不尽相同,主要有两种声音:

1. 因为TCP需要确认通信双方的序列号,所以,A要对B的序列号确认;

2. 防止已经失效的连接请求报文段突然又传到服务端,因而产生错误。

第二条主要来自于谢希仁老师的《计算机网络》,第7版在P239。

书中举了一个例子:A发出的第一个连接请求报文段没有丢失,而是在网络中滞留,以致延迟到连接释放以后的某个时间才到达B,B接收到这个失效的报文段之后,就认为是新的连接请求,于是接受连接请求,分配资源,但是后续A并没有数据发送过来,这样B的资源就白白浪费了。于是,三次握手可以避免这种情况。

面试的时候,我答的就是第二条,面试官反驳说,服务器都会有超时机制,资源的浪费还会被回收,这个不是主要原因。

那什么是主要原因呢?下面说一下我的分析(最后补充面试官的答案)。

首先我依然认为第二条的说法是正确的,因为第二条就是来自 RFC793,原话是这样的:

The principle reason for the three-way handshake is to prevent old duplicate connection initiations from causing confusion.

翻译过来就是第二条:防止失效的重复的连接请求造成困扰。

但是,RFC中所表述的重点在:通过三次握手,通信双方能够正确交换序列号并正常通信,而不是造成资源浪费。(有点第一条的味道)。

RFC中举了下面的例子来说明该情况,这也是区别于第一条的本质所在。

TCP A TCP B

1. CLOSED LISTEN

2. SYN-SENT --> ...

3. (duplicate) ... --> SYN-RECEIVED

4. SYN-SENT

5. SYN-SENT --> --> LISTEN

6. ... --> SYN-RECEIVED

7. SYN-SENT

8. ESTABLISHED --> --> ESTABLISHED

Recovery from Old Duplicate SYN

在第3行,B接收到了A已经失效的序列号为90的报文段,认为是新的连接请求,于是状态由LISTEN变成了SYN-RECEIVED;

在第4行,A接收到了B对于失效的连接请求的确认,但是注意,在A这边,91这个序列号已经失效了,使用91是无法与B进行通信的,而B的状态在第3行中不是LISTEN了,怎么再次建立连接呢?

在第5行A向B发送了控制位RST(reset)为1的报文段,将连接状态重置,所以B的状态回到了LISTEN;

接着在第6行B接收到序列号为100的连接请求,于是接下来就可以正常进行三次握手。

可以看到,第三次握手不一定会发送正确的ACK报文段,而是有可能重置B的连接状态的。假如没有第三次握手,在有失效连接报文段的情况下,A认为B的确认无效,无法使用91序列号,B却已经建立连接,通信就无法进行下去,所以必须要有第三次握手。

PS:面试官的解释:

A向B第一次发送的报文段可能在网络中滞留,而后A可能发送了一个序列号也一样的报文段,但是第一个报文段先到达B,于是建立连接并对A确认,A也认为连接建立了,但是后续通信的内容可能不是第一个TCP请求计划的那样,双方在数据格式以及加密解密上肯能存在不一致的情况,通信会发生错误。

当时听的时候就感觉有问题(不过当时被唬住了),后来想一想,他的说法完全没有道理,相同的连接请求,完全无法区分,就可以认为是同一个,之后的数据通信是按照最新的连接来的,一定不会产生通信的错误。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值