两将军问题和TCP三次握手

news/2024/7/24 11:46:31 标签: 分布式, java, 区块链, python, bootstrap

df80574083691b0dd7173f27517d1a0d.gif

两将军问题,又被称为两将军悖论、两军问题, 是一个经典的计算机思想实验。

首先, 为避免混淆,我们需要认识到两将军问题虽然与拜占庭将军问题相关,但两者不是一个东西。拜占庭将军问题是一个更通用的两将军问题版本, 通常在分布式系统故障容错、区块链中广泛讨论也会犹豫。

1.两将军问题

769f2c0ef0d1724a81b912ac115d570b.png

两支军队,驻扎在两个山头,准备攻击山谷里的同一伙敌人,两将军只有同时发起进攻才能获胜,两将军约定攻击时间的的唯一方式是派遣信使通过山谷,山谷处于敌占区。
如果信使被俘获了,那么攻击信息将会丢失。

现象一:A将军先派遣信使向 B 将军传递“晚上 10 点一起进攻”,但是 A 将军不知道信使能否穿越敌占区,由于担心自己成为唯一进攻方,A 将军可能会犹豫是否按计划进攻; 此时 B 将军收到后可以派遣信使确认收到,B的信使也可能被俘获,由于担心A没有收到确认信号而退缩,B将军也会犹豫;再次确认也不能解决,因为再次确认的新信使也可能被俘获。因此交替确认是无止尽的。

现象二:将军A派遣信使,过了很长时间未收到回复,将军A不知道是自己的信使被俘获了还是将军B的确认信使被俘获了。

我们意识到即使双方不断确认已收到对方的上一条信息,也无法确保对方已与自己达成(同一时间攻击的)共识

两将军问题是无解的,目前的tcp三次握手、四次挥手都是工程解(这个一会再聊)。 

2.两将军问题的头脑风暴

许多人试图解决/缓解双将军问题,提出了一些能落地的实践。

这里我们依旧假设通道的不确定性,信使只会被俘获,但是不会叛变篡改。

7c23e7e8b4e01663a6a82f4e4f7f02e3.gif

2.1 霰弹打鸟

如果A将军每次派遣100名信使(编号1到100),期待B将军最差也能收到一名信使的信息。

B将军根据收到的信使数量,评估这条通道的可靠性,并根据概率也派遣合适数量的确认信使。

eg:  A将军派遣100信使,B将军收到10名信使的信息,B将军基本可确认这条信道可靠度为10%,B将军最少应派出10名信使(根据概率会有1名信使到达对岸)。

2.2 间歇性重试

霰弹打鸟的姿势太费信使了,但至少可帮助B将军提高信心,达成共识。

还有一种少费信使(并能提高将军信心)的策略,假设跨越山谷到达对岸并返回耗时20min, A将军可间隔20min派遣信使到对岸,直到收到对岸B将军的首次信使确认(就不再派遣)。

以上两种策略是对速度和成本的权衡,采用哪一种取决于哪一种策略更适合我们遇到的问题。

3. 为什么说tcp三次握手[1]是双将军问题的工程解?

0a974201fcb9373699673b2fa4fc8481.png

知乎上有个问题: TCP 为什么是三次握手,而不是两次或四次?[2]
有三个回答角度。

  •  TCP 为什么是三次握手,而不是两次或四次?- 朋克雪球兔的回答 - 知乎[3]

  •   (TCP 为什么是三次握手,而不是两次或四次?- 车小胖的回答 - 知乎[4]

  •  TCP 为什么是三次握手,而不是两次或四次?- wuxinliulei的回答 - 知乎[5]

希望大家仔细读一读。

首先我们要知道:

三次握手是为了在两个方向上同步(syn)序列号(seq=m),同步一次序列号需要一去一回两个包,俩方向就4个包。第2,3个包由一侧发出可以合并到一起所以最后三个包

但是根据双将军问题,谁说一来一回两个包就能确保同步成功。

为了缓解双将军问题,tcp3次握手增加了超时重试的机制。(注意:重试只在信息同步的发起方)

第一个包:A发送给B的SYN中途丢失,没有到达B

A会周期性超时重传,直到收到B的确认。

第二个包,即是发送给A的SYN+ACK 中途丢失,没有到达A

B会周期性超时重传,直到收到A的确认, 实际上第一次包:A因为没有收到ACK确认,也会重传)

第三个包:即A发送给ACK 中途丢失,没有到达B

A发完ACK,单方面认为tcp Established状态,而B显然认为tcp为Active状态。

a. 假定此时双方都没有数据发送,B会周期性超时重传,直到收到A的确认,收到之后B的TCP 连接也为 Established状态,双向可以发包。

b. 假定此时A有数据发送,B收到A的 Data + ACK,自然会切换为established 状态,并接受A的 Data。

c. 假定B有数据发送,数据发送不了,会一直周期性超时重传SYN + ACK,直到收到A的确认才可以发送数据。

  • • https://finematics.com/two-generals-problem/

    • https://www.bilibili.com/read/cv16604716

总结

本文记录了两将军问题: 对于不可靠信道,无数次确认都不能百分百达成可靠共识

TCP 三次握手是在两个方向确认包的序列号, 增加了超时重试, 是两将军问题的一个工程解。(本文部分内容提炼自知乎,感谢这届网友的智慧)

引用链接

[1] tcp三次握手: https://blog.csdn.net/weixin_35942339/article/details/112733885
[2] TCP 为什么是三次握手,而不是两次或四次?: https://www.zhihu.com/question/24853633/answer/573627478
[3] TCP 为什么是三次握手,而不是两次或四次?- 朋克雪球兔的回答 - 知乎: https://www.zhihu.com/question/24853633/answer/200721662
[4] (TCP 为什么是三次握手,而不是两次或四次?- 车小胖的回答 - 知乎: https://www.zhihu.com/question/24853633/answer/115173386
[5] TCP 为什么是三次握手,而不是两次或四次?- wuxinliulei的回答 - 知乎: https://www.zhihu.com/question/24853633/answer/63668444

点“”戳“在看

体现态度很有必要!


http://www.niftyadmin.cn/n/1864412.html

相关文章

Go语言正/反向代理的姿势

先重温一下什么叫反向代理,正向代理。鹅厂二面,nginx回忆录[1]所谓正向,反向代理取决于代理的是出站请求,还是入站请求。正向代理:代理的出站请求, 客户端能感知到代理程序,架构上距离客户端更近…

你认识的C# foreach语法糖,真的是全部吗?

本文的知识点其实由golang知名的for循环陷阱发散而来, 对应到我的主力语言C#, 其实牵涉到闭包、foreach。为了便于理解,我重新组织了语言,以倒叙结构行文。 先给大家提炼出一个C#题:观察for、foreach闭包的差异 左边输…

项目管理概述

项目管理 项目是为创造独特的产品、服务或成果而进行的临时性工作。 临时性:指的是有开始、结束时间,而不是指时间很短 独特性:项目中某些可交付成果或者活动中的某些元素是重复的,但项目仍然具有独特性 项目管理让项目目标落地&…

项目运行环境

项目运行环境 影响项目的两大因素 事业环境因素 客观存在,对项目可能有帮助,也可能有阻碍,项目经理只能去应对,而不能回避 所有公司外部的环境,包括法律法规、市场环境、政府行业标准等公司内组织文化、员工能力、基础…

组织体系

组织体系 ​ 单个组织内多种因素交织影响创造出的一个独特系统,会对在该系统内运行的项目造成影响,其因素包括: 管理要素治理框架组织结构类型 运行项目的过程中需要应对治理框架和组织结构带来的制约 项目管理办公室(PMO&#…

项目经理角色

项目经理角色 项目经理的作用 对团队成果负责,需要从整体角度看待团队产品,以便进行规划、协调、完成 项目经理和职能经理 项目经理:由执行组织委派,领导团队实现项目目标的个人。通常项目经理会花大量时间进行沟通协调&#xf…

空跑任务,满足CPU使用率合规要求

语言:golang 适用系统:linux 用途:空跑任务,满足CPU使用率合规要求 使用方法:go run cpulimit.go 0.35 // 百分之35%使用率 package mainimport ("fmt""io/ioutil"// "math""os&q…

获取CPU使用率(golang)

语言:golang 适用系统:linux 用途:获取CPU使用率 原文地址:https://stackoverflow.com/questions/11356330/how-to-get-cpu-usage package mainimport ("fmt""io/ioutil""strconv""strings&q…