当前位置: 首页 > news >正文

TCP三次握手四次挥手

TCP头部

微信图片_20190201231040

源端口和目的端口在TCP层确定双方进程,序列号表示的是报文段数据中的第一个字节号,ACK表示确认号,该确认号的发送方期待接收的下一个序列号,即最后被成功接收的数据字节序列号加1,这个字段只有在ACK位被启用的时候才有效。

当新建一个连接时,从客户端发送到服务端的第一个报文段的SYN位被启用,这称为SYN报文段,这时序列号字段包含了在本次连接的这个方向上要使用的第一个序列号,即初始序列号ISN,之后发送的数据是ISN加1,因此SYN位字段会消耗一个序列号,这意味着使用重传进行可靠传输。而不消耗序列号的ACK则不是。

头部长度(图中的数据偏移)以32位字为单位,也就是以4bytes为单位,它只有4位,最大为15,因此头部最大长度为60字节,而其最小为5,也就是头部最小为20字节(可变选项为空)。

三次握手四次挥手图例

三次握手是指发送了3个报文段,四次挥手是指发送了4个报文段。注意,SYN和FIN段都是会利用重传进行可靠传输的。

下图是TCP三次握手四次挥手的时序图:

a

下图为TCP协议状态机:

b

ACK —— 确认,使得确认号有效。
RST —— 重置连接(经常看到的reset by peer)就是此字段搞的鬼。
SYN —— 用于初始化一个连接的序列号。
FIN —— 该报文段的发送方已经结束向对方发送数据。

当一个连接被建立或被终止时,交换的报文段只包含TCP头部,而没有数据。

三次握手

要弄清TCP建立连接需要几次交互才行,我们需要弄清建立连接进行初始化的目标是什么。

TCP进行握手初始化一个连接的目标是:分配资源、初始化序列号(通知peer对端我的初始序列号是多少)。知道了初始化连接的目标,那么要达成这个目标的过程就简单了,握手过程可以简化为下面的四次交互:

  1. client端首先发送一个SYN包告诉Server端我的初始序列号是X。
  2. Server端收到SYN包后回复给client一个ACK确认包,告诉client说我收到了。
  3. 接着Server端也需要告诉client端自己的初始序列号,于是Server也发送一个SYN包告诉client我的初始序列号是Y。
  4. Client收到后,回复Server一个ACK确认包说我知道了。

整个过程4次交互即可完成初始化。

为什么要进行三次握手

客户端和服务端通信前要进行连接,“3次握手”的作用就是双方都能明确自己和对方的收、发能力是正常的。

第一次握手:客户端发送网络包,服务端收到了。这样服务端就能得出结论:客户端的发送能力、服务端的接收能力是正常的。

第二次握手:服务端发包,客户端收到了。这样客户端就能得出结论:服务端的接收、发送能力,客户端的接收、发送能力是正常的。 从客户端的视角来看,我接到了服务端发送过来的响应数据包,说明服务端接收到了我在第一次握手时发送的网络包,并且成功发送了响应数据包,这就说明,服务端的接收、发送能力正常。而另一方面,我收到了服务端的响应数据包,说明我第一次发送的网络包成功到达服务端,这样,我自己的发送和接收能力也是正常的。

第三次握手:客户端发包,服务端收到了。这样服务端就能得出结论:客户端的接收、发送能力,服务端的发送、接收能力是正常的。 第一、二次握手后,服务端并不知道客户端的接收能力以及自己的发送能力是否正常。而在第三次握手时,服务端收到了客户端对第二次握手作的回应。从服务端的角度,我在第二次握手时的响应数据发送出去了,客户端接收到了。所以,我的发送能力是正常的。而客户端的接收能力也是正常的。

经历了上面的三次握手过程,客户端和服务端都确认了自己的接收、发送能力是正常的。之后就可以正常通信了。

四次挥手

TCP进行断开连接的目标是:回收资源、终止数据传输。

由于TCP是全双工的,需要Peer两端分别各自拆除自己通向Peer对端的方向的通信信道。这样需要四次挥手来分别拆除通信信道,就比较清晰明了了。

  1. Client发送一个FIN包来告诉Server我已经没数据需要发给Server了。
  2. Server收到后回复一个ACK确认包说我知道了。
  3. 然后server在自己也没数据发送给client后,Server也发送一个FIN包给Client告诉Client我也已经没数据发给client了。
  4. Client收到后,就会回复一个ACK确认包说我知道了。

到此,四次挥手,这个TCP连接就可以完全拆除了。

为什么要进行四次挥手

TCP连接是双向传输的对等的模式,就是说双方都可以同时向对方发送或接收数据。

当有一方要关闭连接时,会发送指令告知对方,我要关闭连接了。这时对方会回一个ACK,此时一个方向的连接关闭。但是另一个方向仍然可以继续传输数据,等到发送完了所有的数据后,会发送一个FIN段来关闭此方向上的连接。接收方发送ACK确认关闭连接。

注意,接收到FIN报文的一方只能回复一个ACK, 它是无法马上返回对方一个FIN报文段的,因为结束数据传输的“指令”是上层应用层给出的,我只是一个“搬运工”,我无法了解“上层的意志”。

为什么握手是三次而挥手要四次

这是因为服务端在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。

而关闭连接时,当收到对方的FIN报文时,仅仅表示对方不再发送数据了但是还能接收数据,己方是否现在关闭发送数据通道,需要上层应用来决定,因此,己方ACK和FIN一般都会分开发送。

##################

转载于:https://www.cnblogs.com/amunote/p/10344415.html

相关文章:

  • C++类中的特殊成员函数
  • ES搜索引擎集群模式搭建【Kibana可视化】
  • spring cloud gateway 源码解析(4)跨域问题处理
  • 有赞电商云应用框架设计
  • JS专题之继承
  • 阿里云服务器怎么升级配置?升级有哪些限制?
  • UniDAC使用教程(五):数据加密
  • React-生命周期杂记
  • 关于VirtualDom的知识点
  • 【划重点】MySQL技术内幕:InnoDB存储引擎
  • [CF703D]Mishka and Interesting sum/[BZOJ5476]位运算
  • 极限编程 (Extreme Programming) - 发布计划 (Release Planning)
  • 生成、打包、部署和管理应用程序及类型(3):将模块合并成程序集
  • windows下使用nginx调试简介
  • Ajax 知识
  • 【407天】跃迁之路——程序员高效学习方法论探索系列(实验阶段164-2018.03.19)...
  • 【技术性】Search知识
  • 【跃迁之路】【585天】程序员高效学习方法论探索系列(实验阶段342-2018.09.13)...
  • JavaScript 是如何工作的:WebRTC 和对等网络的机制!
  • javascript 总结(常用工具类的封装)
  • JAVA并发编程--1.基础概念
  • JAVA多线程机制解析-volatilesynchronized
  • JS笔记四:作用域、变量(函数)提升
  • mockjs让前端开发独立于后端
  • nodejs实现webservice问题总结
  • Spring Cloud Alibaba迁移指南(一):一行代码从 Hystrix 迁移到 Sentinel
  • thinkphp5.1 easywechat4 微信第三方开放平台
  • 阿里云容器服务区块链解决方案全新升级 支持Hyperledger Fabric v1.1
  • 聊聊flink的TableFactory
  • 前端性能优化--懒加载和预加载
  • 思维导图—你不知道的JavaScript中卷
  • 小程序01:wepy框架整合iview webapp UI
  • - 转 Ext2.0 form使用实例
  • ​云纳万物 · 数皆有言|2021 七牛云战略发布会启幕,邀您赴约
  • (30)数组元素和与数字和的绝对差
  • (ZT)薛涌:谈贫说富
  • (附源码)spring boot智能服药提醒app 毕业设计 102151
  • (七)微服务分布式云架构spring cloud - common-service 项目构建过程
  • *Algs4-1.5.25随机网格的倍率测试-(未读懂题)
  • .mysql secret在哪_MySQL如何使用索引
  • .NET/C# 解压 Zip 文件时出现异常:System.IO.InvalidDataException: 找不到中央目录结尾记录。
  • .NET国产化改造探索(一)、VMware安装银河麒麟
  • .sh 的运行
  • /dev下添加设备节点的方法步骤(通过device_create)
  • @value 静态变量_Python彻底搞懂:变量、对象、赋值、引用、拷贝
  • [ 隧道技术 ] 反弹shell的集中常见方式(二)bash反弹shell
  • [ 云计算 | Azure 实践 ] 在 Azure 门户中创建 VM 虚拟机并进行验证
  • [AIGC] 使用Curl进行网络请求的常见用法
  • [Angular 基础] - 数据绑定(databinding)
  • [AutoSar]状态管理(五)Dcm与BswM、EcuM的复位实现
  • [C#]C# OpenVINO部署yolov8图像分类模型
  • [C/C++]数据结构 循环队列
  • [E单调栈] lc2487. 从链表中移除节点(单调栈+递归+反转链表+多思路)
  • [github配置] 远程访问仓库以及问题解决
  • [HackMyVM]靶场 Quick3