TCP 为什么是三次握手,而不是两次或四次?

转自知乎

Tcp是个状态鸡
Tcp是个双功通信的状态鸡

有了这两个前提,我们来枚举所有A鸡和B鸡组成的分布式系统关于信道的所有状态。

A鸡

  1. A->B是通的还是不通。我们用AB表示,值域是y/n。
  2. B->A是通的还是不通。我们用BA表示,值域也是y/n。

B鸡

  1. A->B是通的还是不通。我们用AB表示,值域是y/n。
  2. B->A是通的还是不通。我们用BA表示,值域也是y/n

很显然这是关于信道状态的穷举啦。没有异议吧。

初始状态
A鸡: AB = n, BA = n
B鸡: AB = n, BA = n

事实上,通信领域所有的握手都是协商状态。我没见过不是协商状态叫握手的。跟人类一样吧,我握住你的手,我确认你不是***,你确认我不是***,就是不是***这个变量两个人达成共识状态。那些弄比特币的神棍把这个叫共识,我觉得很有道理,因为在我心里一致就是时间序相关的,其实就是这么回事。下面A鸡和B鸡组成的state machine得到什么状态才能通信呢。我们描绘一下可以通信的状态。

通信状态
A鸡: AB = y, BA = y
B鸡: AB = y, BA = y

我们怎么从初始的状态迁移到通信状态呢,其实我们又不是心有灵犀一点通,我们只能通过交换消息。我们还是按照装逼的方式说事件吧。

event 1:
A发一个sync给B,此时没有发生状态迁移。因为A也不知道B能不能收到,显然两个信道都没有资格设置成y。

event 2:
B收到A的sync,此时B知道A->B是通的。系统的状态机鸡迁移。

A鸡: AB = n, BA = n
B鸡: AB = y, BA = n

event 3:
B发送上一个sync的ack + 自己的sync给A,这个时候其实很明显,跟event1一样,对整个系统的状态鸡没影响的。

event 4:
A收到B发的ack + sync,A知道A->B是通的,因为他通过这条信道发消息收到回复了。同时A知道B->A是通的,因为他从B收到消息了。所以整个系统的状态鸡。迁移到:

A鸡: AB = y, BA = y
B鸡: AB = y, BA = n
玩到这里已经用了两个消息了。然而还是没有达到可通信的状态。因为B鸡还是不确定B到A的信道是不是通的。这两边就不能够进行通信,因为两个通信主体就信道状态没有达成共识呀。答案只能是

event 5:
A回复B的sync发给B一个ack。这时候,也不会发生状态迁移。

event 6:
B收到A回复的ack,这时候B知道我发给A消息是可以收到回复的,因此B认为B->A的信道是通的。因此我可以很happy的把状态迁移到

A鸡: AB = y, BA = y
B鸡: AB = y, BA = y
game over

这个状态两个节点就A到B和B到A两个信道是通的达成了共识。所以需要三条消息因为有双向信道各个方向各有一个变量表示信道是否是通的,跟序号毫无关系,楼上扯序号的都是瞎掰的。序号的存在因为tcp是流协议。后面还需要排序。

全部评论

相关推荐

头像
不愿透露姓名的神秘牛友
04-02 20:12
点赞 评论 收藏
转发
点赞 收藏 评论
分享
牛客网
牛客企业服务