这是一个看似很“简单”的问题,但貌似并没有一个官方统一的答案。搜索了相关的资料,列举出一些答案。

以下部分转载自:tcp建立连接为什么需要三次握手

  • 在《计算机网络》一书中其中有提到,三次握手的目的是“为了防止已经失效的连接请求报文段突然又传到服务端,因而产生错误”,这种情况是:一端(client)A发出去的第一个连接请求报文并没有丢失,而是因为某些未知的原因在某个网络节点上发生滞留,导致延迟到连接释放以后的某个时间才到达另一端(server)B。本来这是一个早已失效的报文段,但是B收到此失效的报文之后,会误认为是A再次发出的一个新的连接请求,于是B端就向A又发出确认报文,表示同意建立连接。如果不采用“三次握手”,那么只要B端发出确认报文就会认为新的连接已经建立了,但是A端并没有发出建立连接的请求,因此不会去向B端发送数据,B端没有收到数据就会一直等待,这样B端就会白白浪费掉很多资源。如果采用“三次握手”的话就不会出现这种情况,B端收到一个过时失效的报文段之后,向A端发出确认,此时A并没有要求建立连接,所以就不会向B端发送确认,这个时候B端也能够知道连接没有建立。(知乎上对上面的解释的评论:这个解答不是问题的本质,这个课本很多知识比较片面。问题的核心在于保证信道数据传输的可靠性,避免资源浪费仅仅是一个小的弱原因,不重要。)

  • 问题的本质是,信道是不可靠的,但是我们要建立可靠的连接发送可靠的数据,也就是数据传输是需要可靠的。在这个时候三次握手是一个理论上的最小值,并不是说是tcp协议要求的,而是为了满足在不可靠的信道上传输可靠的数据所要求的。

我们再来考虑,如果不是三次握手会出现什么情况呢:

假设有A和B两端要进行通信,
1, 第一次:首先A发送一个(SYN)到B,意思是A要和B建立连接进行通信;

如果是只有一次握手的话,这样肯定是不行的,A压根都不知道B是不是收到了这个请求。
2, 第二次:B收到A要建立连接的请求之后,发送一个确认(SYN+ACK)给A,意思是收到A的消息了,B这里也是通的,表示可以建立连接;

如果只有两次通信的话,这时候B不确定A是否收到了确认消息,有可能这个确认消息由于某些原因丢了。
3, 第三次:A如果收到了B的确认消息之后,再发出一个确认(ACK)消息,意思是告诉B,这边是通的,然后A和B就可以建立连接相互通信了;

这个时候经过了三次握手,A和B双方确认了两边都是通的,可以相互通信了,已经可以建立一个可靠的连接,并且可以相互发送数据。
4, 第四次:这个时候已经不需要B再发送一个确认消息了,两边已经通过前三次建立了一个可靠的连接,如果再发送第四次确认消息的话,就浪费资源了。

如果第二个报文段B发出的(SYN+ACK)分别发送的话,也是可以理解为四次,但是被优化了,一起发送了。
超时重传机制,

(1) 如果第一个包,A发送给B请求建立连接的报文(SYN)如果丢掉了,A会周期性的超时重传,直到B发出确认(SYN+ACK);
(2) 如果第二个包,B发送给A的确认报文(SYN+ACK)如果丢掉了,B会周期性的超时重传,直到A发出确认(ACK);
(3) 如果第三个包,A发送给B的确认报文(ACK)如果丢掉了,

A在发送完确认报文之后,单方面会进入ESTABLISHED的状态,B还是SYN_RCVD状态
如果此时双方都没有数据需要发送,B会周期性的超时发送(SYN+ACK),直到收到A的确认报文(ACK),此时B也进入ESTABLISHED状态,双方可以发送数据;
如果A有数据发送,A发送的是(ACK+DATA),B会在收到这个数据包的时候自动切换到ESTABLISHED状态,并接受数据(DATA);
如果这个时候B要发送数据,B是发送不了数据的,会周期性的超时重传(SYN+ACK)直到收到A的确认(ACK)B才能发送数据。
三次握手牵扯到的状态转换

LISTEN 表示socket已经处于listen状态了,可以建立连接;
SYN_SENT 表示socket在发出connect连接的时候,会首先发送SYN报文,然后等待另一端发送的确认报文(ACK),表示这端已经发送完SYN报文了;
SYN_RCVD 表示一端已经接收到SYN报文了;
ESTABLISHED 表示已经建立连接了,可以发送数据了。

作者:朋克雪球兔
链接:https://www.zhihu.com/question/24853633/answer/200721662
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

看了很多答案,只有一个答案提到“两军问题”,其他的答案,长篇累牍或者抖机灵感觉都没回答到点子上。其实两次四次四十次,在工程上都是可以接受的。如果让我设计一个非常重要,对可靠性要求很高的通讯协议,我也完全可能采用更多次握手的设计。亦或者涉及对实时性要求很高的通讯,也完全可以设计成不握手(udp)的协议。TCP之所以使用三次握手,完全是一种为了解决“两军问题”所采用的折衷的设计。所谓“两军问题”,就是红军想告诉蓝军明天下午一起对敌开火,那么红军会派信使1号跑过去告诉蓝军,蓝军收到消息再派信使2号告诉红军收到,注意,这时蓝军并不知道红军是否收到蓝军的回复。因此需要红军收到回复再派信使3号告诉蓝军收到回复,而此时红军也不知道蓝军是否收到回复,因此蓝军收到信使3号的消息再派信使4号…可以看到,由于信息有可能丢失,为了保证信息传达的确定性,我们需要进行很多次传递。互相通信的次数越多,那么这个信息传递到的概率就越大。tcp采用三次握手,就是为了尽可能可靠,然而,这也仅是一种选择。

tcp建立连接为什么需要三次握手相关推荐

  1. 为什么tcp不采用停等协议_为什么TCP建立连接协议是三次握手,而关闭连接却是四次握手呢?...

    看到了一道面试题:"为什么TCP建立连接协议是三次握手,而关闭连接却是四次握手呢?为什么不能用两次握手进行连接?",想想最近也到金三银四了,所以就查阅了相关资料,整理出来了这篇文章 ...

  2. startupinfo为什么需要初始化_为什么 TCP 建立连接要三次握手

    为什么这么设计(Why's THE Design)是一系列关于计算机领域中程序设计决策的文章,我们在这个系列的每一篇文章中都会提出一个具体的问题并从不同的角度讨论这种设计的优缺点.对具体实现造成的影响 ...

  3. TCP建立连接三次握手和释放连接四次握手

    TCP建立连接三次握手和释放连接四次握手     [尊重原创,转载请注明出处]http://blog.csdn.net/guyuealian/article/details/52535294 在谈及T ...

  4. mobaxterm为什么无法连接_为什么 TCP 建立连接需要三次握手

    为什么这么设计(Why's THE Design)是一系列关于计算机领域中程序设计决策的文章,我们在这个系列的每一篇文章中都会提出一个具体的问题并从不同的角度讨论这种设计的优缺点.对具体实现造成的影响 ...

  5. TCP建立连接『三次握手』

    三次握手 TCP建立连接 TCP 是面向连接的协议,所以使用 TCP 前必须先建立连接,而建立连接是通过三次握手而进行的. 面试回答: TCP/IP协议是传输层一个面向的连接的安全的协议,三次握手的协 ...

  6. TCP建立连接与释放连接

    TCP建立连接与释放连接   最近复习准备<计算机网络>考试,感觉TCP协议建立连接与释放连接这两个过程比较重要,所以把自己理解的部分写下来. 1.建立连接:(三次握手) (1)客户端发送 ...

  7. 为什么TCP建立连接需要三次握手

    为什么TCP建立连接需要三次握手 很简单,因为TCP的目的是相对高效地建立可靠的连接. 虽然说2次握手,请求方就已经能够确认双方路径已经没有问题了.但是接受方这边接收到的信息却仅仅是,你发起了建立连接 ...

  8. TCP建立连接三次握手及其断开过程

    TCP是一个面向连接的服务,也就是在数据通信之前,发送端需要建立连接.等数据发送之后,就要断开连接. 1. TCP建立连接 TCP建立连接需要三次握手.建立的过程如下: 2. TCP断开连接 转载于: ...

  9. TCP建立连接的三次握手

    TCP建立连接的三次握手 TCP头的构成 TCP建立连接的过程就是三次握手,三次握手成功完成,TCP连接就建立了.在三次握手之前先看一下TCP报文中的TCP头由哪些部分组成. 上图中有几个字段需要重点 ...

最新文章

  1. JAVA springboot微服务b2b2c电子商务系统(十三)断路器聚合监控(Hystrix Turbine)
  2. 相似三角形_JAVA
  3. 调整分区个数_在重装系统的过程中,硬盘如何分区呢?
  4. 信息系统项目管理师--项目整体管理
  5. Linux文件系统与日志分析(inode、inode节点耗尽故障处理、文件备份和恢复、日志文件管理)
  6. 酷派手机android版本,酷派大神的手机系统是什么?酷派大神能升级安卓4.3吗?...
  7. Spark入门(八)之WordCount
  8. android 三星 白色,时尚实用都拥有 白色Android手机盘点
  9. python之虚拟环境
  10. Java中Javadoc的{@link}与@see的简单区别
  11. 网络性能优化(NAPI)
  12. Android学习总结(3)——Handler深入详解
  13. 学习笔记6—pandas中ix,loc,iloc有什么区别?
  14. 小程序登录及用户信息和手机号的获取
  15. Maven 手动安装JAR包到本地maven仓库后,但在项目中依旧报错找不到JAR包解决方法
  16. EtherCAT运动控制卡开发教程之Qt(上):开发环境配置与简单运动控制应用
  17. 清理window日志垃圾.bat
  18. 取消idm浏览网页时的自动下载
  19. 关键字生成参考文案查找相似款,特卖淘宝达人有福了,自媒体时代的懒人助手
  20. securecrt 远程映射端口

热门文章

  1. 夫曼编码译码系统课程设计实验报告(含源代码c++_c语言),哈夫曼编码译码系统课程设计实验报告(含源代码C++_C语言)[1]...
  2. Java牛客专项练习2020.12.10
  3. Windows 9信息曝光:统一开发接口、整合Cortana到任务栏
  4. Linux 常用命令
  5. 公司技术管理角度看C++游戏程序员发展
  6. 安装 Git ( Windows、linux、Mac)
  7. dependency 中的 classifier属性
  8. 数据库主键自增插入显示值
  9. 搭建webpack基础配置
  10. 手机按键中控运行思路的个人理解