关于TCP三次握手和两次握手的思考

  • TCP连接需要握手的原因
  • 两次握手的可行性分析

TCP连接需要握手的原因

TCP协议是一个非常常见的全双工协议,它保证了数据的可靠传输。

使用TCP服务的程序一般需要三次握手来建立TCP的连接,根据RFC文档可知,TCP三次握手主要是让发送方和接收方知道各自的序列号,利用序列号来维护数据的可靠传输。

TCP协议三次握手流程如下:
seq表示序列号,ack表示应答号,ack = y表示该机器希望下次接收来的序列号为y,SYN = 1表示这是一个建立序列号同步的过程,ACK = 1表示这是一个应答消息
客户端随机生成一个序列号seq = x,向服务端发送该请求(SYN = 1,seq = x, ACK = 0, ack = ?)
服务端接收到客户端的请求之后,同样生成一个随机序列号seq = y,向客户端发送应答及其序列号(SYN = 1, seq = y, ACK = 1, ack = x+1)
客户端接收到接收的消息之后,向服务端发送一个应答消息(SYN = 0, seq = x+1,ACK = 1,ack = y+1)

在第一次,第二次握手中,是不允许携带数据的,而SYN = 1表示默认消耗一个数据,所以第二次握手中消息中的ack = x+1。
而第三次握手一般是不携带数据的,所以三次握手后客户端向服务端发送的第一个消息的seq = x+1

两次握手的可行性分析

但是为什么是三次握手而不是两次呢?经过两次握手之后发送方和接收方已经知道了双方的序列号了,是不是已经可以实现同步了?这是一个网络上很多人讨论的问题,以下我的一些分析,不保证对,希望大家一起讨论。

我们可以假设TCP握手协议只有两次:
客户端随机生成一个序列号seq = x,向服务端发送该请求(SYN = 1,seq = x, ACK = 0, ack = ?)
服务端接收到客户端的请求之后,同样生成一个随机序列号seq = y,向客户端发送应答及其序列号(SYN = 1, seq = y, ACK = 1, ack = x+1)

分析一个成功的场景:
客户端向服务端进行第一次握手,服务端向客户端发送应答并发送自己的序列号
此时,客户端因为已经接受到服务端的应答,所以可以确定自己的序列号已经被服务端知道,所以它下一步可以发送实际的数据了
而服务端向客户端发送了应答,它默认客户端已经知道了自己的序列号,所以分配连接的资源,等待客户端的下一个数据
若一切运行良好,客户端下一步向服务端发送大小为9的数据(SYN = 0,seq = x+1,ACK = 0, ack = y+1)
服务端接收后向客户端发送回应(SYN = 0, seq = y+1, ACK = 1, ack = x+11)

上面是运行良好的情况,但是网络中丢包现象是极为普遍的,我们可以再假设以下的情景
1.客户端发送成功了,接收端的应答丢失
此时客户机的状态:第一次握手请求(SYN = 1,seq = x, ACK = 0, ack = ?)迟迟没有回应,认为握手请求丢失,重传握手请求
服务器的状态为:已经为客户端分配了资源,等待客户端的第一条消息(期待消息的序列号为seq = x+1)。但此时接收到的消息为(SYN = 1,seq = x, ACK = 0, ack = ?),可以再次发送一次应答信号(SYN = 1, seq = y, ACK = 1, ack = x+1),并期待这次连接成功
若这次没有产生丢包,则可以进行正常的TCP通信了

2.客户端发送的第一次的消息在网络中发生了延时,再次发送第二次消息,此时,先后两次握手陆续到达,请求连接,服务端应答消息正常抵达客户端
此时客户机状态,两条连接请求都成功,但客户端会认为只有第二条请求成功
服务器状态:服务器接收到第一条握手请求后,分配相应资源,发送应答消息,之后再次接收到一个相同客户端的第一次握手请求
这时会出现两种情况:1.服务端有能力区分这两种请求是来自同一个客户端的相同请求,将第二次到来的握手请求丢弃处理。2.服务器没有能力区分这两种请求是来自于同一个客户端的相同请求,同样为这条请求分配资源,等待客户端的应答
若是第二种情况呢,虽然最后服务器到达一定时间后会自动断开TCP连接,收回资源,但是也造成了比较大的资源浪费。(不过这样或许能减少一些网络的流量?)
对于第一种情况呢,服务端分辨是否为同一请求有三个重要参考条件(端口号,IP,SYN = 1时的seq)
从我们可以在一个浏览器中开两个网页访问同一个网站,可以看出根据前两个条件服务端无法做出区分
接下来分析seq的情况,我们假设客户端重发握手请求时与前一次都是相同的seq,这样服务端或许就可以根据此消息中的同一个端口号,IP,seq判断出是同一个握手请求了(再加一个标志位或许可以不利用seq解决这种浪费资源的情况?)。

3.第三种思考是从TCP是一个全双工的协议来看的。我们之前的思考都是建立在TCP连接后客户端先主动向服务端发送消息。当然,实际我并没有想到什么服务端先向客户端发送数据的例子
若是有需要建立连接后服务端先向客服端发送消息的情况呢?
经过以下流程
两次握手都运行良好
客户端随机生成一个序列号seq = x,向服务端发送该请求(SYN = 1,seq = x, ACK = 0, ack = ?)
服务端接收到客户端的请求之后,同样生成一个随机序列号seq = y,向客户端发送应答及其序列号(SYN = 1, seq = y, ACK = 1, ack = x+1)
此时服务端的状态 :准备发送一个序列号为y+1的数据(根据默认协议)
此时客户端的状态:准备接收一个序列号为y+1的数据
若是服务端发送的应答信息产生了丢包呢,此时服务端想要发送一个序列号为y+1的数据,但是客户端并不知道服务端的序列号。
此时就出现了无法解决的的错误
当然,由于博主学识有限,并未想到有关于服务端先向客服端发送协议的情况

这样分析之后,握手两次或许可行,不过,由于第2,3种情况的原因,再加上TCP的收到消息就给出应答的机制,或许还有一些博主没想到的方面,TCP最终选择了三次握手。毕竟,3次握手肯定比2次握手来得更为可靠。

关于TCP三次握手和两次握手的思考相关推荐

  1. TCP三次握手,握的是啥?

    目录 前言 先要弄清楚两个概念 抓包分析 建立连接过程中的Sequence number 数据传输过程中的Sequence number 为什么TCP建立连接不是两次握手也不是四次握手? 补充阅读 前 ...

  2. 第三次握手为什么没有序列号_图解TCP三次握手与四次分手

    TCP三次握手和四次挥手不管是在开发还是面试中都是一个非常重要的知识点,它是我们优化web程序性能的基础.但是大部分教材都对这部分解释的比较抽象,本文我们就利用wireshark来抓包以真正体会整个流 ...

  3. TCP三次握手详解及面试题

    为什么必须是三次握手?   大家都知道传输层(点击这里去传输层)中的TCP协议是面向连接的,提供可靠的连接服务,其中最出名的就是三次握手和四次挥手,今天先讲解三次握手(四次挥手点这里),如下图   喜 ...

  4. TCP三次握手四次挥手过程及其中的状态量

    网上看到过一些有关TCP三次握手四次挥手的过程,觉得有必要总结一下了,对于了解TCP的过程还是有帮助的 1.变量含义 SYN表示建立连接, FIN表示关闭连接, ACK表示响应, PSH表示有 DAT ...

  5. TCP三次握手原理详解

    TCP/IP协议不是TCP和IP这两个协议的合称,而是指因特网整个TCP/IP协议族. 从协议分层模型方面来讲,TCP/IP由四个层次组成:网络接口层.网络层.传输层.应用层. TCP协议:即传输控制 ...

  6. TCP三次握手及其相关问题

    三次握手的过程 第一次握手:客户端发送一个SYN=1,序列号随机生成的报文给服务器(假设为j),进入SYN_SENT状态: 第二次握手:服务器收到客户端SYN=1的报文之后,知道客户端请求建立连接.发 ...

  7. pythonsocket中tcp通信接收不到数据_TCP 为什么三次握手而不是两次握手(正解版)...

    先说结论 为了实现可靠数据传输, TCP 协议的通信双方, 都必须维护一个序列号, 以标识发送出去的数据包中, 哪些是已经被对方收到的. 三次握手的过程即是通信双方相互告知序列号起始值, 并确认对方已 ...

  8. TCP三次握手过程,如果两次握手会怎么样?

    让我们来看一个故事,读完这个故事,我相信你和面试官的对话会非常愉快. 网络帝国的崛起 随着时间的流逝,计算机帝国的子民耐不住寂寞,他们好想去外面的世界看看,去其他的计算机家中串串门,他们经常抱怨,为什 ...

  9. 两将军问题和TCP三次握手

    两将军问题,又被称为两将军悖论.两军问题, 是一个经典的计算机思想实验. 首先, 为避免混淆,我们需要认识到两将军问题虽然与拜占庭将军问题相关,但两者不是一个东西.拜占庭将军问题是一个更通用的两将军问 ...

最新文章

  1. POJ 2516 Minimum Cost 最小费用流
  2. jboss linux 性能,搭建jprofiler对jboss性能监控
  3. flume package遇到的问题
  4. 2019.8.13 sdfzoier
  5. 【Lucy-Richardson去卷积】迭代加速算法
  6. tar打包的时候忽略一些目录
  7. CSS分别设置Input样式(按input类型
  8. Linux NTP时间服务器搭建
  9. 阿里再度开源重磅技术!95% 程序员都需要了解
  10. 深度学习2.0-43.AE实战与VAE实战
  11. Java类与类,类与接口,接口与接口关系
  12. 红帽认证有效期多久?
  13. python qq群文件_Python随笔|抓取QQ群成员头像
  14. 金蝶K3 Wise—BOM批量多级展开
  15. OrCAD(二)功能详情与实战总结
  16. 《 Python List列表全实例详解系列(三)》——列表添加元素(4种方法)
  17. linux测网速几种方式
  18. Linux dos2unix命令
  19. poi数据获取、学校poi分布、医院poi分布、公园分布、地铁分布、道路网
  20. 射频IC卡和IC卡读卡器的成本分析

热门文章

  1. 运算放大器工作原理及选择
  2. BUUCTF:7月做题记录
  3. gitlab ci/cd预设变量
  4. [附源码]java+ssm计算机毕业设计家电维修服务平台771x3(源码+程序+数据库+部署)
  5. linux临界区原理,临界区的实现原理
  6. 计算机图形学 光栅化_计算机图形学中的光栅扫描和随机扫描显示
  7. matlab正弦光栅条纹及调整
  8. 如何正确使用OPcache优化系统性能
  9. 布林线均值回归策略(股票)
  10. 冯雷老师:提高360评估结果准确性的3个关键