三次握手

相关参数的描述:

消息类型 描述
SYN 同步序列编号 用来初始化和建立连接的
ACK 确认字符 帮助对方确认收到的SYN消息
SYN-ACK 本地的SYN消息和较早的ACK数据包
FIN 用来断开连接

SYN:同步序列编号,是TCP/IP建立连接使用的握手信号。在客户机和服务器之间建立TCP连接时,首先会发送一个信号。客户端在接收到SYN消息时,就会在自己的段内生成一个随机值X。

SYN-ACK:服务器收到SYN后,打开客户端连接,发送一个SYN-ACK作为答复。确认号设置为比接收到的序列号多一个,即X+1,服务器为数据包选择的序列号是另一个随机数 Y

ACK:确认字符,表示发来的数据已确认接收无误。最后,客户端将ACK发送给服务器。序列号被设置为接收的确认值即Y+1

最开始,客户端和服务器端都是处于CLOSED closed状态。先是服务器端主动监听某个端口,处于LISTEN状态。listen状态

  1. 客户端会随机初始化序号(client_isn),将此序号置于TCP首部的序号字段中,同时把SYN标志位置为1,表示SYN报文。接着把SYN报文发送到服务器端,表示想服务器发送连接,该报文不包含应用层的数据,之后客户端处于SYN-SENT状态(请求连接状态)。

  2. 服务器端收到客户端的SYN报文后,首先服务器端会自己初始化自己的序列号(server_isn),将次序号填入TCP首部的序号中,其次把TCP首部确认应答号字段填入client_isn + 1,接着把SYN和ACK标志位置为1,最后将该报文发送给客户端,该报文不包含应用层的数据,之后服务器处于 SYN-RCVD状态。接收状态

  3. 客户端收到服务器端报文后,向服务器端响应最后一个应答报文,首先该应答报文TCP首部ACK标志位置为1,其次确认应答号字段填入server_isn + 1,最后把报文发送给服务器端,报文中携带客户到服务器的数据,之后客户端处于ESTABLISHED状态(established连接成功状态)。

  4. 服务器端收到客户端的应答报文户,也进入ESTABLISHED状态。

第三次握手是可以携带数据的,前两次握手是不可以携带数据的,一旦完成三次握手,双方都处于 ESTABLISHED 状态,此时连接就已建立完成,客户端和服务端就可以相互发送数据了。

举例:

小明-客户端 小红-客户端

小明给小红打电话,接通后,小明说可以听到吗,相当于是连接建立

小红给小明回应,能听到我说话吗,相当于请求响应。

小明听到小红的回应后,好的,想防御连接确认,之后小明和小红就可以通话/交换信息。

总结:

首先客户端向服务端发送连接请求,并发送SYN报文,之后处于请求连接状态;之后服务器端收到客户端的SYN报文后,将SYN和ACK置为1,将报文发送给客户端,之后服务器由监听状态转换为接收状态,此时客户端接收到了服务器的报文后,将相关的数据和报文一起发送给服务器。最后服务器和客户端都进了连接成功状态。

clinent_isn:客户端序列号 server_isn : 服务器端序列号

  • 前置条件:客户端和服务器处于关闭状态。首先服务端进入监听状态

  • 第一次:客户端向服务器端发送SYN(=1)报文,并进入请求连接状态(随机初始化clinent_isn)

  • 第二次:服务器端接收到客户端的SYN请求后,将SYN和ACK置为1,将报文发送给客户端,服务器端进入接收状态(随机初始化server_isn,并将clinent_isn + 1 )

  • 第三次:客户端收到了服务器的ACK报文后,将发送的数据和报文一起发送给服务器端,进入连接成功状态(server_isn + 1)

  • 最后条件:客户端和服务器端都进入了连接成功状态

为什么要三次握手?

三次握手时为了建立可靠的通信信道,收到通讯,简单来说就是数据的发送和接收,而三次握手最主要的目的就是双方确认自己与对方的发送和接收是正常的。

第一次握手,客户端什么都不能确认;Server确认了对方发送正常自己接收正常

第二次握手:客户端确认自己和客户端发送、接收正常;服务器端确认客户端发送正常,自己接收正常

第三次握手:客户端确认了,自己和对方接收、发送正常;服务器端确认自己和客户端发送、接收正常。

三次握手保证了服务器端和客户端双方都发送和接收正常。

因为三次握手才能保证双方具有接收和发送的能力。

为什么是三次握手?不是两次、四次?

因为三次握手才能保证双方具有接收和发送的能力。

为什么三次握手才可以初始化Socket、序列号和窗口大小并建立 TCP 连接?

  • 可以阻止重复历史连接的初始化(主要原因)

    为了防止旧的重复连接初始化造成混乱,如果是两次连接,无法确定当前连接是否是历史连接,三次握手则可以在客户端准备发送第三次报文时,客户端有足够的时间来判断是否为历史连接。

    • 如果是历史连接(序列号过期或超时),则第三次握手发送的报文是 RST 报文,以此中止历史连接;

    • 如果不是历史连接,则第三次发送的报文是 ACK 报文,通信双方就会成功建立连接;

  • 可以同步双方的初始序列号

    两次握手只保证了一方的初始序列号能被对方成功接收,没办法保证双方的初始序列号都能被确认接收。

  • 可以避免资源浪费

    如果只有「两次握手」,当客户端的 SYN 请求连接在网络中阻塞,客户端没有接收到 ACK 报文,就会重新发送 SYN ,由于没有第三次握手,服务器不清楚客户端是否收到了自己发送的建立连接的ACK 确认信号,所以每收到一个 SYN 就只能先主动建立一个连接,这会造成什么情况呢? 如果客户端的 SYN 阻塞了,重复发送多次 SYN 报文,那么服务器在收到请求后就会建立多个冗余的无效链接,造成不必要的资源浪费。

TCP 建立连接时,通过三次握手能防止历史连接的建立,能减少双方不必要的资源开销,能帮助双方同步初始化序列号。序列号能够保证数据包不重复、不丢弃和按序传输。不使用「两次握手」和「四次握手」的原因:

  • 两次握手:无法防止历史连接的建立,会造成双方资源的浪费,也无法可靠的同步双方序列号;

  • 四次握手:三次握手就已经理论上最少可靠连接建立,所以不需要使用更多的通信次数。

第 2 次握手传回3了 ACK,为什么还要传回 SYN?

接收端传回发送吨所发送的ACK是为了告诉客户端,我接收到的信息确实就是你所发送的信号,这表明从客户端到服务器端的通信是正常的,而回传SYN则是为了建立并确认从服务器端到客户端的通信。

四次挥手

通过四次挥手,双方都可以主动断开连接,断开连接后主机中的资源将被释放。

四次挥手:每个方向都需要一个FIN和一个ACK

主动关闭连接的,才有 TIME_WAIT 状态。

  • 客户端打算关闭连接,会发送一个TCP首部FIN标志位置为1的报文,即FIN报文,之后客户端进入FIN_WAIT_1 状态

  • 服务器端收到报文后,向客户端发送ACK应答报文,接着服务器端进入CLOSED_WAIT 状态(等待关闭状态)。

  • 客户端收到服务器端的ACK应答报文后,进入FIN_WAIT_2状态

  • 服务器处理完数据后,向客户端发送FIN报文,之后服务器端进入, LAST_ACK 状态

  • 客户端收到服务器端的FIN报文后,回应一个ACK应答报文,进入TIME_WAIT状态。

  • 服务器端收到了ACK应答报文后,就进入了CLOSED状态,到此服务器端已经完成连接的关闭。

  • 客户端在经过2MSL一段时间后,自动进入CLOSED状态,客户端也完成连接的关闭

举例:

1. A和B打电话,通话即将结束,A说我没有什么可以说的了,B回答我知道了,但是B可能还没有说完,A有不能要求B跟着自己的节奏结束通话,于是B可能又说一些,最后B说我说完了,A回答我知道了,通话结束。

2.

  • 客户端---小明 服务器端---小红

  • 小明对小红说,我所有的东西都说完了,我要挂电话了

  • 小红说,收到,我这边这些一些东西没说

  • 经过若干秒后,小红也说完了,小红说,我说完了,现在可以挂断了

  • 小明收到消息后,又等了若干时间后,挂断了电话

总结

  • 客户端发送一个FIN,用来关闭客户端到服务器的数据传送
  • 服务器收到这个FIN,它发回一个ACK,确认序号为收到的序号加1。和SYN一样,一个FIN将占用一个序号。
  • 服务器端关闭与客户端的连接,发送一个FIN给客户端
  • 客户端发回ACK报文确认,并将确认序号设置为收到序号加1

任何一方都可以在数据传送结束后发出连接释放的通知,待对方确认后进入半关闭状态。当另一方也没有数据再发送的时候,则发出连接释放通知,对方确认后就完全关闭了TCP连接。

四次挥手双方发 FIN 包的过程,就能理解为什么需要四次了?

  • 关闭连接后,客户端向服务端发送FIN时,仅仅表示客户端不再发送数据了,但是还是可以接收数据

  • 服务器端收到客户端FIN报文时,先回一个ACK应答报文,而服务端可能还有数据需要处理和发送,等服务器端不再发送数据时,才发送FIN报文给客户端来表示同意现在关闭连接

从上面过程可知,服务端通常需要等待完成数据的发送和处理,所以服务端的 ACK 和 FIN 一般都 会分开发送,从而比三次握手导致多了一次。

为什么 TIME_WAIT 等待的时间是 2MSL?

        MSL是Maximum Segment Lifetime,报文最大生存时间,它是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。因为TCP报文基于是IP协议的,而IP头中有一个TTL字段,是IP数据报可以经过的最大路由数,每经过一个处理的它的路由器此值就减一,当此值为0,则数据报将被丢弃,同时发送ICMP报文通知源主机

MSL 与 TTL 的区别: MSL 的单位是时间,而 TTL 是经过路由跳数。所以 MSL 应该要大于等于 TTL消耗为 0 的时间,以确保报文已被自然消亡。

TIME_WAIT 等待 2 倍的 MSL,比较合理的解释是: 网络中可能存在来自发送方的数据包,当这些发送方的数据包被接收方处理后又会向对方发送响应,所以一来一回需要等待 2 倍的时间

总结:

TCP协议如何保证可靠传输?

  1. 应用数据被分割成 TCP 认为最适合发送的数据块。
  2. TCP 给发送的每一个包进行编号,接收方对数据包进行排序,把有序数据传送给应用层。
  3. 校验和: TCP 将保持它首部和数据的检验和。这是一个端到端的检验和,目的是检测数据在传输过程中的任何变化。如果收到段的检验和有差错,TCP 将丢弃这个报文段和不确认收到此报文段。
  4. TCP 的接收端会丢弃重复的数据。
  5. 流量控制: TCP 连接的每一方都有固定大小的缓冲空间,TCP 的接收端只允许发送端发送接收端缓冲区能接纳的数据。当接收方来不及处理发送方的数据,能提示发送方降低发送的速率,防止包丢失。TCP 使用的流量控制协议是可变大小的滑动窗口协议。 (TCP 利用滑动窗口实现流量控制)
  6. 拥塞控制: 当网络拥塞时,减少数据的发送。
  7. ARQ 协议: 也是为了实现可靠传输的,它的基本原理就是每发完一个分组就停止发送,等待对方确认。在收到确认后再发下一个分组。
  8. 超时重传: 当 TCP 发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段。

TCP的三次挥手、四次握手相关推荐

  1. TCP三次挥手四次握手(面试总结)

    1. 为什么建立连接协议是三次握手,而关闭连接却是四次握手呢? 全双工通信. 这是因为服务端的LISTEN状态下的SOCKET当收到SYN报文的建连请求后,它可以把ACK和SYN(ACK起应答作用,而 ...

  2. TCP三次挥手四次握手

    三次握手: 客户端发起: 1.向服务器端发送报文SYN=1,ACK=0;客户端进入SYN-SEND状态. 2.服务端收到SYN=1,ACK=0的请求报文,向客户端返回确认报文SYN=1,ACK=1,服 ...

  3. TCP协议三步挥手与四步挥手

    关于TCP协议 TCP(Transmission Control Protocol, 传输控制协议)是一种面向连接的.可靠的.基于字节流的传输层通信协议.与之对应的是UDP(User Datagram ...

  4. TCP两次挥手,你见过吗?那四次握手呢?

    我们都知道,TCP是个面向连接的.可靠的.基于字节流的传输层通信协议. 那这里面提到的"面向连接",意味着需要 建立连接,使用连接,释放连接. 建立连接是指我们熟知的TCP三次握手 ...

  5. 活久见!TCP两次挥手,你见过吗?那四次握手呢?

    文章持续更新,可以微信搜一搜「小白debug」第一时间阅读,回复[教程]获golang免费视频教程.本文已经收录在GitHub https://github.com/xiaobaiTech/golan ...

  6. Android Studio --- [学习笔记]RadioButton、CheckBox、ImageView、ListView、TCP的三次握手

    说明 源代码 在2.x里有TCP的三次挥手与四次握手,先对它进行简单的回答(百度).预计在下一篇里,会继续说明TCP 接上一篇: Android Studio - > [学习笔记]Button. ...

  7. 由一次线上故障来理解下 TCP 三握、四挥 Java 堆栈分析到源码的探秘

    本文导读: 生产故障场景介绍 TCP 建连三次握手过程 TCP 断连四次挥手过程 结合 Java 堆栈剖析源码 再从堆栈中找到"罪魁祸首" 问题优化方案总结 1.生产故障场景介绍 ...

  8. 一文搞懂TCP的三次握手和四次挥手

    目录 1.三次握手 2.四次挥手 3.11种状态名词解析 TCP的三次握手和四次挥手实质就是TCP通信的连接和断开. 三次握手:为了对每次发送的数据量进行跟踪与协商,确保数据段的发送和接收同步,根据所 ...

  9. java tcp 三次握手_用Java代码分析TCP的三次握手四次挥手过程

    (1)客户端发送一个带SYN标志的TCP报文到服务器.这是三次握手过程中的报文1. (2) 服务器端回应客户端的,这是三次握手中的第2个报文,这个报文同时带ACK标志和SYN标志.因此它表示对刚才客户 ...

最新文章

  1. lua 访问oracle,lua链接oracle解决方法与步骤
  2. KVM虚拟化存储管理
  3. T4文本模板转换过程
  4. php 从根目录 开始创建,php创建多级目录的方法
  5. VC++6.0使用GDI++出现'ULONG_PTR'未定义和'token' 未定义的解决办法
  6. vs自带iis局域网调试
  7. jQuery UI加入效果
  8. cocos2d-x 3.2 DrawNode 绘图API
  9. Mac电脑快捷键效率办公技巧
  10. 阶段5 3.微服务项目【学成在线】_day02 CMS前端开发_15-webpack研究-webpack-dev-server-程序调试...
  11. m1也能用的视频无损放大软件:topaz video enhance ai mac版
  12. 敏捷与CMMI的同与不同
  13. 微信图片盗链php,微信公众号图片如何实现反防盗链接
  14. 经典算法题-----猴子吃桃的问题
  15. 控制BLDC资料汇总
  16. python3豆瓣电影排行榜爬取
  17. 01 DIY流星观测站
  18. charts练习总结
  19. TFX发展简史/《Towards ML Engineering: A Brief History Of TensorFlow Extended (TFX)》
  20. 兴业银行信息科技类笔试分享

热门文章

  1. [问题] springboot2报错 Exception during pool initialization. java.sql.SQLException
  2. 树莓派变身影音播放器
  3. u盘安装完linux系统没镜像,U盘刻录kali linux启动盘提示找不到镜像解决方案
  4. 超快速ocr文字识别 mac版
  5. 微信小程序实现代码高亮
  6. 面对就业我们是否还在徘徊那么你就看看这篇文章把
  7. 《学Unity的猫》——第五章:规范Unity的工程目录结构
  8. c# Parse和TryParse的性能差距
  9. 【C语言练习题】5位运动员参加了10米台跳水比赛,有人让他们预测比赛结果:A选手说:B第二,我第三;B选手说:我第二,E第四;C选手说:我第一,D第二;D选手说:C最后,我第三;E选手说:……
  10. android自定义键盘监听输入框,Android 自定义键盘的车牌输入框