两张动图-彻底明白TCP的三次握手与四次挥手

2023-11-17

背景描述

通过上一篇中网络模型中的IP层的介绍,我们知道网络层,可以实现两个主机之间的通信。但是这并不具体,因为,真正进行通信的实体是在主机中的进程,是一个主机中的一个进程与另外一个主机中的一个进程在交换数据。IP协议虽然能把数据报文送到目的主机,但是并没有交付给主机的具体应用进程。而端到端的通信才应该是应用进程之间的通信。

UDP,在传送数据前不需要先建立连接,远地的主机在收到UDP报文后也不需要给出任何确认。虽然UDP不提供可靠交付,但是正是因为这样,省去和很多的开销,使得它的速度比较快,比如一些对实时性要求较高的服务,就常常使用的是UDP。对应的应用层的协议主要有 DNS,TFTP,DHCP,SNMP,NFS 等。

TCP,提供面向连接的服务,在传送数据之前必须先建立连接,数据传送完成后要释放连接。因此TCP是一种可靠的的运输服务,但是正因为这样,不可避免的增加了许多的开销,比如确认,流量控制等。对应的应用层的协议主要有 SMTP,TELNET,HTTP,FTP 等。


常用的熟知端口号

应用程序 FTP TFTP TELNET SMTP DNS HTTP SSH MYSQL
熟知端口 21,20 69 23 25 53 80 22 3306
传输层协议 TCP UDP TCP TCP UDP TCP TCP TCP

TCP的概述

TCP把连接作为最基本的对象,每一条TCP连接都有两个端点,这种断点我们叫作套接字(socket),它的定义为端口号拼接到IP地址即构成了套接字,例如,若IP地址为192.3.4.16 而端口号为80,那么得到的套接字为192.3.4.16:80。

TCP报文首部

  1. 源端口和目的端口,各占2个字节,分别写入源端口和目的端口;
  2. 序号,占4个字节,TCP连接中传送的字节流中的每个字节都按顺序编号。例如,一段报文的序号字段值是 301 ,而携带的数据共有100字段,显然下一个报文段(如果还有的话)的数据序号应该从401开始;
  3. 确认号,占4个字节,是期望收到对方下一个报文的第一个数据字节的序号。例如,B收到了A发送过来的报文,其序列号字段是501,而数据长度是200字节,这表明B正确的收到了A发送的到序号700为止的数据。因此,B期望收到A的下一个数据序号是701,于是B在发送给A的确认报文段中把确认号置为701;
  4. 数据偏移,占4位,它指出TCP报文的数据距离TCP报文段的起始处有多远;
  5. 保留,占6位,保留今后使用,但目前应都位0;
  6. 紧急URG,当URG=1,表明紧急指针字段有效。告诉系统此报文段中有紧急数据;
  7. 确认ACK,仅当ACK=1时,确认号字段才有效。TCP规定,在连接建立后所有报文的传输都必须把ACK置1;
  8. 推送PSH,当两个应用进程进行交互式通信时,有时在一端的应用进程希望在键入一个命令后立即就能收到对方的响应,这时候就将PSH=1;
  9. 复位RST,当RST=1,表明TCP连接中出现严重差错,必须释放连接,然后再重新建立连接;
  10. 同步SYN,在连接建立时用来同步序号。当SYN=1,ACK=0,表明是连接请求报文,若同意连接,则响应报文中应该使SYN=1,ACK=1;
  11. 终止FIN,用来释放连接。当FIN=1,表明此报文的发送方的数据已经发送完毕,并且要求释放;
  12. 窗口,占2字节,指的是通知接收方,发送本报文你需要有多大的空间来接受;
  13. 检验和,占2字节,校验首部和数据这两部分;
  14. 紧急指针,占2字节,指出本报文段中的紧急数据的字节数;
  15. 选项,长度可变,定义一些其他的可选的参数。

TCP连接的建立(三次握手)

在这里插入图片描述

最开始的时候客户端和服务器都是处于CLOSED状态。主动打开连接的为客户端,被动打开连接的是服务器。

  1. TCP服务器进程先创建传输控制块TCB,时刻准备接受客户进程的连接请求,此时服务器就进入了LISTEN(监听)状态;
  2. TCP客户进程也是先创建传输控制块TCB,然后向服务器发出连接请求报文,这是报文首部中的同部位SYN=1,同时选择一个初始序列号 seq=x ,此时,TCP客户端进程进入了 SYN-SENT(同步已发送状态)状态。TCP规定,SYN报文段(SYN=1的报文段)不能携带数据,但需要消耗掉一个序号。
  3. TCP服务器收到请求报文后,如果同意连接,则发出确认报文。确认报文中应该 ACK=1,SYN=1,确认号是ack=x+1,同时也要为自己初始化一个序列号 seq=y,此时,TCP服务器进程进入了SYN-RCVD(同步收到)状态。这个报文也不能携带数据,但是同样要消耗一个序号。
  4. TCP客户进程收到确认后,还要向服务器给出确认。确认报文的ACK=1,ack=y+1,自己的序列号seq=x+1,此时,TCP连接建立,客户端进入ESTABLISHED(已建立连接)状态。TCP规定,ACK报文段可以携带数据,但是如果不携带数据则不消耗序号。
  5. 当服务器收到客户端的确认后也进入ESTABLISHED状态,此后双方就可以开始通信了。
    三次握手

为什么TCP客户端最后还要发送一次确认呢?

一句话,主要防止已经失效的连接请求报文突然又传送到了服务器,从而产生错误。

如果使用的是两次握手建立连接,假设有这样一种场景,客户端发送了第一个请求连接并且没有丢失,只是因为在网络结点中滞留的时间太长了,由于TCP的客户端迟迟没有收到确认报文,以为服务器没有收到,此时重新向服务器发送这条报文,此后客户端和服务器经过两次握手完成连接,传输数据,然后关闭连接。此时此前滞留的那一次请求连接,网络通畅了到达了服务器,这个报文本该是失效的,但是,两次握手的机制将会让客户端和服务器再次建立连接,这将导致不必要的错误和资源的浪费。

如果采用的是三次握手,就算是那一次失效的报文传送过来了,服务端接受到了那条失效报文并且回复了确认报文,但是客户端不会再次发出确认。由于服务器收不到确认,就知道客户端并没有请求连接。

TCP连接的释放(四次挥手)

在这里插入图片描述

数据传输完毕后,双方都可释放连接。最开始的时候,客户端和服务器都是处于ESTABLISHED状态,然后客户端主动关闭,服务器被动关闭。

  1. 客户端进程发出连接释放报文,并且停止发送数据。释放数据报文首部,FIN=1,其序列号为seq=u(等于前面已经传送过来的数据的最后一个字节的序号加1),此时,客户端进入FIN-WAIT-1(终止等待1)状态。 TCP规定,FIN报文段即使不携带数据,也要消耗一个序号。
  2. 服务器收到连接释放报文,发出确认报文,ACK=1,ack=u+1,并且带上自己的序列号seq=v,此时,服务端就进入了CLOSE-WAIT(关闭等待)状态。TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。
  3. 客户端收到服务器的确认请求后,此时,客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)
  4. 服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1,ack=u+1,由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为seq=w,此时,服务器就进入了LAST-ACK(最后确认)状态,等待客户端的确认。
  5. 客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,ack=w+1,而自己的序列号是seq=u+1,此时,客户端就进入了TIME-WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2 ∗ * MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。
  6. 服务器只要收到了客户端发出的确认,立即进入CLOSED状态。同样,撤销TCB后,就结束了这次的TCP连接。可以看到,服务器结束TCP连接的时间要比客户端早一些。

四次挥手

为什么客户端最后还要等待2MSL?

MSL(Maximum Segment Lifetime),TCP允许不同的实现可以设置不同的MSL值。

第一,保证客户端发送的最后一个ACK报文能够到达服务器,因为这个ACK报文可能丢失,站在服务器的角度看来,我已经发送了FIN+ACK报文请求断开了,客户端还没有给我回应,应该是我发送的请求断开报文它没有收到,于是服务器又会重新发送一次,而客户端就能在这个2MSL时间段内收到这个重传的报文,接着给出回应报文,并且会重启2MSL计时器。

第二,防止类似与“三次握手”中提到了的“已经失效的连接请求报文段”出现在本连接中。客户端发送完最后一个确认报文后,在这个2MSL时间中,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失。这样新的连接中不会出现旧连接的请求报文。

为什么建立连接是三次握手,关闭连接确是四次挥手呢?

建立连接的时候, 服务器在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。
而关闭连接时,服务器收到对方的FIN报文时,仅仅表示对方不再发送数据了但是还能接收数据,而自己也未必全部数据都发送给对方了,所以己方可以立即关闭,也可以发送一些数据给对方后,再发送FIN报文给对方来表示同意现在关闭连接,因此,己方ACK和FIN一般都会分开发送,从而导致多了一次。

如果已经建立了连接,但是客户端突然出现故障了怎么办?

TCP还设有一个保活计时器,显然,客户端如果出现故障,服务器不能一直等下去,白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。




本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

两张动图-彻底明白TCP的三次握手与四次挥手 的相关文章

  • 一份关于jvm内存调优及原理的学习笔记

    JVM 一 虚拟机的基本结构 1 jvm整体架构 类加载子系统 负责从文件系统或者网络中加载class信息 存入方法区中 方法区 Perm 存放加载后的class信息 包括静态方法 jdk1 6以前包含了常量池 参数 XX PermSize
  • Android获取SHA1

    SHA1 怎么获取 不同签名文件的 SHA1 值不同 可以参考下面三种获取 SHA1 值的方式 1 通过 Android Studio 编译器获取 1 打开 Android Studio 的 Terminal 工具 2 输入命令 keyto
  • html从一个页面跳转至另一个html页面的子页面

    假设从1 html跳转至2 html的子页面 则 在1 html中添加点击事件 a href user customerManageNew class u btn add span class swf add span a 然后在后台con
  • Android中 @id 与 @+id 区别

    Android 中的组件需要用一个int 类型的值来表示 这个值也就是组件标签中的id 属性值 id 属性只能接受资源类型的值 也就是必须以 开头的值 例如 id abc id xyz等 如果在 后面使用 表示当修改完某个布局文件并保存后
  • shell脚本中的几个括号总结(小括号/大括号/花括号)

    转自 http www cnblogs com hanyan225 archive 2011 10 06 2199652 html Shell的强大是毋庸置疑的 方便了我们也迷惑了我们 比如这些杂七杂八的括号 一向自认聪明的我也傻傻分不清了
  • uni-app request回调函数内无法使用this.

    微信小程序开发中 通常会在 request成功的回调函数中修改本地的属性 如果直接使用this 会有类似的提示无法修改 gt Cannot set property xxx of undefined at api request succe
  • 【代码随想录】双指针法刷题

    双指针法刷题 移除元素 删除有序数组中的重复项 移动零 比较含退格的字符串 有序数组的平方 反转字符串 替换空格 反转链表 递归 迭代 头插法 删除链表的倒数第 N 个节点 环形链表 快慢指针 环形链表 II 链表相交 三数之和 四数之和
  • no matching distrubution found for setuptools

    1 问题描述 1 安装setuptools rust 报错 no matching distrubution found for setuptools 实际上已经安装过好几次 2 执行命令之后 python3 7 m pip show Se
  • 数据库日期处理(转)

    通常 你需要获得当前日期和计算一些其他的日期 例如 你的程序可能需要判断一个月的第一天或者最后一天 你们大部分人大概都知道怎样把日期进行分割 年 月 日等 然后仅仅用分割出来的年 月 日等放在几个函数中计算出自己所需要的日期 在这篇文章里
  • jupyter运行环境安装与使用

    jupyter运行环境安装与使用 所有文章不设限 我们相遇偶然 相散坦然 互不打扰 各自安好 向阳而生 一 利用python环境 使用pip命令安装 1 安装jupyter的方式 此处省去对于python环境的相关配置 直接介绍如何安装 j
  • 【计算机网络11】应用层之DHCP

    文章目录 1 IP地址的分配 2 DHCP 2 1 DHCP 分配 IP 地址的 4 个阶段 1 IP地址的分配 IP地址按照分配方式 可以分为 静态 IP 地址 动态 IP 地址 静态 IP 地址 手动设置 适用场景 不怎么挪动的台式机
  • 分享全球外贸免费发布产品的平台-跨境贸易平台

    免费发布产品到平台有哪些好处 发布产品增加一些曝光率 提高你产品在谷歌搜索结果的曝光率 为你的官网引流 提高权重 http www ecrobot com 综合 世界综合贸易网站精选前十名 http www ectrade com 亚洲 易
  • ElasticsearchTemplate 常用API使用,看这一篇就够了

    ElasticsearchTemplate 常用API 文章目录 ElasticsearchTemplate 常用API 前言 源码分析 基本使用 单字符串全文查询 指定字段模糊查询 指定字段短语匹配 完全匹配查询 多字段匹配某一个值 完全
  • mysql忘记密码重置密码步骤

    1 使用管理员权限打开cmd窗口 win r后输入cmd 然后按Ctrl Shift Enter 2 停止mysql服务 如上图net stop mysql 3 找到mysql安装目录下的my ini文件 使用管理员权限打开 4 在 mys
  • 内存溢出的原因和解决办法

    1 堆溢出 这种场景最为常见 报错信息 java lang OutOfMemoryError Java heap space 原因 1 代码中可能存在大对象分配 2 可能存在内存泄露 导致在多次GC之后 还是无法找到一块足够大的内存容纳当前
  • QT入门级小项目(vs2015+qt designer混合编程)

    划重点 在vs里面使用c 和qt designer开发一个动态计算加法的小工具 最近想做一个界面 而且QT也是自己一直想学的东西 于是就查了一下python qt和c 与Qt开发的方法 这篇文章就是使用c 开发QT界面 网上关于QT的开发文
  • 深入理解【测试计划】

    工作快一年了 软件测试的理论还没有真正系统深入的研究过 除了平常的业务工作 自己更多的时间花在了程序设计上 接触了那么多的业务 我想是时候结合业务 好好研究一下测试的基础了 未完待续

随机推荐

  • 计算机视觉大作业:EdgeConnect论文阅读

    复现 一 环境配置 运行环境 Python 3 6 6 PyTorch 1 10 0 NVIDIA GPU CUDA 10 2 cuDNN 8 2 Python包 numpy 1 14 3 mkl scipy 1 0 1 future 0
  • 逻辑回归公式推导

    一 预测函数 1 第一个式子称为sigmoid函数 先了解一下sigmoid函数 通过sigmoid函数与线性回归预测函数的联立 即可得到逻辑回归的预测函数 2 即是说 逻辑回归的预测函数实际上是 通过线性回归的预测函数得到一个预测值 连续
  • Hello! protobuf——编译与安装(c++版)

    目录 前言 一 protobuf是什么 二 protobuf官方路径 三 protobuf编译安装 1 安装前建议 2 cmake使用 1 cmake介绍 2 命令行介绍 3 编译选项介绍 4 cmake安装 3 windows下使用nma
  • ChatGPT-4来袭,留学申请文书面临挑战如何破局?

    近日 ChatGPT再次 进化 其最新版本ChatGPT 4又掀高潮 其生产者OpenAI 称 ChatGPT 4是最先进的系统 能生产更安全和更有用的回复 和上一代相比 GPT 4拥有了更广的知识面和更强的解决问题能力 在创意 视觉输入和
  • [Vue warn]: Error in v-on handler: “TypeError: Cannot read properties of undefined (reading ‘value‘)

    1 问题描述 antd 下拉框选择的时候报了这个错误
  • 第一章----行列式知识点汇总

    目录 线性代数 1 来自b站网课截屏 本人亲自截屏作为笔记 在这里供大家学习分享 需要线性代数全部内容请通过传送门自行下载 第一章 行列式 1 1行列式的定义 二阶行列式的定义 排列与逆序 排列 逆序 定理1 1 1 一个对换 奇偶排列改变
  • Pandas 面板Panel

    一 Panel介绍 Pandas 面板 Panel 是3维数据的存储结构 相当于一个存储 DataFrame 的字典 有3个轴 axis 分别给出描述涉及面板数据的操作的一些语义 具体如下 items axis 0 每个项目对应于内部包含的
  • 推荐系统:GBDT+LR简介

    1 GBDT LR简介 前面介绍的协同过滤和矩阵分解存在的劣势就是仅利用了用户与物品相互行为信息进行推荐 忽视了用户自身特征 物品自身特征以及上下文信息等 导致生成的结果往往会比较片面 而这次介绍的这个模型是2014年由Facebook提出
  • ubuntu通过apt安装软件的安装路径

    jdk usr lib jvm 具体jdk版本 tomcat usr share tomcat具体版本
  • 把ffmpeg放到后台自动运行

    最近一个项目 需要用ffmpeg把rtsp流转成ts流 由于rtsp服务器有可能关闭 需要自动的重启ffmpeg去连接rtsp服务器 1 编写一个用ffmpeg转TS流的脚本rtsp2ts sh ffmpeg i rtsp xx xx xx
  • pyd文件介绍

    pyd一般是python外的其他语言如C C 编写的python扩展模块 即python的一个动态链接库 与dll文件相当 在linux系统中一般为 so文件 也有的时候 为了对python文件进行加密 会把python模块编译成 pyd文
  • Unity基础学习之C#学习(二)

    C 程序三大结构 0 前言 1 分支结构 1 1 if语句 1 2 switch语句 2 循环结构 2 1 while循环 2 2 do while循环 2 3 for循环 最常用 2 4 foreach循环 主要用于迭代遍历 3 brea
  • oracle查询结果添加序列,SQL查询结果增加序列号

    SQL查询记录中增加序列号 根据学生成绩在查询结果中增加排名字段 1 SELECT ROW NUMBER OVER ORDER BY SCORE ASC AS RANK NAME SCORE FROM GRADE ORDER BY SCOR
  • vue-element-admin使用Tinymce富文本插件的踩坑填坑

    vue element admin项目的作者已经封装好了Tinymce富文本组件 我直接在Git上下载demo运用到自己项目里 这是Git地址 https github com PanJiaChen vue element admin 一
  • [0x7FFBFB69D3E0] ANOMALY: meaningless REX prefix used问题的修复

    0x7FFBFB69D3E0 ANOMALY meaningless REX prefix used 困扰了我几个礼拜 导致idea git 用不了 差点重装系统了 今天还好 解决了 用360 各种修复 各种操作 cmd 没有那串东西咯 各
  • 宏观经济浅学20210724

    https www bilibili com video BV1Ng4y1B7ig p 14 8大类 251个基本分类 700个品种 120万个商品
  • 写一篇有关机器学习的论文

    写一篇有关机器学习的论文 需要从以下几个方面进行阐述 机器学习的定义 首先要明确机器学习的定义 并简要介绍其历史发展 机器学习的分类 接着介绍机器学习的分类方法 例如监督学习 非监督学习 半监督学习 强化学习等 机器学习的应用 最后详细阐述
  • 智能城市dqn算法交通信号灯调度_新基建激发AI新动力,助推人工智能产业化落地进程...

    8月7日 9日 由中国计算机学会主办 香港中文大学 深圳 雷锋网联合承办的全球人工智能和机器人峰会在深圳开幕 峰会期间揭晓了 2020AI 最佳成长榜 千方科技旗下博观智能凭借在智慧城市多个细分领域的商用落地实力 斩获 AI 智慧城市 领域
  • python判断语句

    判断语句 if if 语句的判断语法 if 要判断的条件 条件成立时 要做的事情 else语法格式如下 if 要判断的条件 条件成立时 要做的事情 else 条件不成立 要做的事情 逻辑运算 只有多个条件都满足 才能执行后续代码 这个时候需
  • 两张动图-彻底明白TCP的三次握手与四次挥手

    背景描述 通过上一篇中网络模型中的IP层的介绍 我们知道网络层 可以实现两个主机之间的通信 但是这并不具体 因为 真正进行通信的实体是在主机中的进程 是一个主机中的一个进程与另外一个主机中的一个进程在交换数据 IP协议虽然能把数据报文送到目