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

简述TCP三次握手和四次挥手流程

文章目录

  • 前言
  • 三次握手
  • 四次挥手
  • 总结

前言

关于TCP的连接过程,很多从事程序开发的小伙伴应该都听过三次握手,可这三次握手的细节还是有很多人不太清楚的,特别是有些参数记不清楚,我也经常弄错,所以我根据自己的理解画了两张图,将TCP连接和断开的流程简单记录一下,以方便后续查找复习之用。

三次握手

tcp_connect

初始状态:客户端A和服务器B均处于CLOSED状态,然后服务器B创建socket,调用监听接口使得服务器处于LISTEN状态,等待客户端连接。(后续内容用A,B简称代替)

  1. A首先向B发起连接,这时TCP头部中的SYN标识位值为1,然后选定一个初始序号seq=x(一般是随机的),消息发送后,A进入SYN_SENT状态,SYN=1的报文段不能携带数据,但要消耗一个序号。

  2. B收到A的连接请求后,同意建立连接,向A发送确认数据,这时TCP头部中的SYN和ACK标识位值均为1,确认序号为ack=x+1,然后选定自己的初始序号seq=y(一般是随机的),确认消息发送后,B进入SYN_RCVD状态,与连接消息一样,这条消息也不能携带数据,同时消耗一个序号。

  3. A收到B的确认消息后,需要给B回复确认数据,这时TCP头部中的ACK标识位值为1,确认序号是ack=y+1,自己的序号在连接请求的序号上加1,也就是seq=x+1,此时A进入ESTABLISHED状态,当B收到A的确认回复后,B也进入ESTABLISHED状态,至此TCP成功建立连接,A和B之间就可以通过这个连接互相发送数据了。

四次挥手

tcp_disconnect
初始状态:客户端A和服务器B之间已经建立了TCP连接,并且数据发送完成,打算断开连接,此时客户端A和服务器B是等价的,双方都可以发送断开请求,下面以客户端A主动发起断开请求为例。(后续内容用A,B简称代替)

  1. A首先向B发送断开连接消息,这时TCP头部中的FIN标识位值为1,序号是seq=m,m为A前面正常发送数据最后一个字节序号加1得到的,消息发送后A进入FNI_WAIT_1状态,FIN=1的报文段不能携带数据,但要消耗一个序号。

  2. B收到A的断开连接请求需要发出确认消息,这时TCP头部中的ACK标识位值为1,确认号为ack=m+1,而自己的序号为seq=n,n为B前面正常发送数据最后一个字节序号加1得到的,然后B进入CLOSE_WAIT状态,此时就关闭了A到B的连接,A无法再给B发数据,但是B仍然可以给A发数据(此处存疑),同时B端通知上方应用层,处理完成后被动关闭连接。然后A收到B的确认信息后,就进入了FIN_WAIT_2状态。

  3. B端应用层处理完数据后,通知关闭连接,B向A发送关闭连接的消息,这时TCP头部中的FIN和ACK标识位值均为1,确认号ack=m+1,自己的序号为seq=k,(B发出确认消息后有发送了一段数据,此处存疑),消息发送后B进入LAST_ACK状态。

  4. A收到B的断开连接的消息后,需要发送确认消息,这是这时TCP头部中的ACK标识位值为1,确认号ack=k+1,序号为m+1(因为A向B发送断开连接的消息时消耗了一个消息号),然后A进入TIME_WAIT状态,若等待时间经过2MSL后,没有收到B的重传请求,则表明B收到了自己的确认,A进入CLOSED状态,B收到A的确认消息后则直接进入CLOSED状态。至此TCP成功断开连接。

总结

  1. 关于三次握手,参考了很多资料说服务器是被动打开连接,对此有些不解,希望知道的朋友给出提示和建议。

  2. 关于四次挥手,在我的叙述中有两处存疑,就是B收到的A的主动断开请求后,进入CLOSE_WAIT状态,是否还能发送数据到A,参考了一些资料说A不能发数据给B,但是B能发数据给A,并且A也可以接收,但是无论我在Windows环境测试还是Linux环境下测试这种状态A都无法收到B的数据,不知道我是不是理解错了,希望明白原理的小伙伴能解答一下。

  3. 在四次挥手的最后阶段,有一个等待时间2MSL,这个不是一个时间单位,而是一个表明时间段的名词,这段等待时间就是为了在B没收到确认消息时,接收B的重传请求的,如果不等待这一段时间直接进入CLOSED状态,那么B未收到A的确认消息就会发送重传请求,而此时A已经关闭,就不会再给B重传了,其中MSL的是Maximum Segment Lifetime英文的缩写,可简单译为“报文最大生存时间”,也就是说如果B没有收到确认信息,那么在2MSL这段时间内很大概率就会发送重传请求,并且被A收到,RFC 793中规定MSL为2分钟,实际应用中常用的是30秒,1分钟和2分钟等。

  4. 在连接和断开的过程都有提到ACKack,这一点要注意区分,大写的ACK代表TCP头部中6个标识位之一,是表明这是个确认报文,而小写的ack拜师确认序号,表明对方发来的数据到ack这个序号前的都已经收到了。

相关文章:

  • 智能指针(零):分类及简单特性
  • 智能指针(一):auto_ptr浅析
  • 智能指针(二):shared_ptr浅析
  • 智能指针(四):unique_ptr浅析
  • Lua中关于table对象引用传递的注意事项
  • VS2015调试dump文件时提示打不开KERNELBASE.dll
  • Mysql中使用select into语句给变量赋值没有匹配记录时的结果
  • 排序算法系列之(四)——抓扑克牌风格的插入排序
  • linux环境下服务器程序的查看与gdb调试
  • linux环境下运行程序常用的nohup和的区别
  • 排序算法系列之(五)——为目标打好基础的希尔排序
  • linux环境下查找包含指定内容的文件及其所在行数
  • Mysql查询可通过给条件字段添加索引提高查询速度
  • Mysql开启、查看慢查询日志
  • IP地址常见分类:A类、B类、C类、D类、E类
  • -------------------- 第二讲-------- 第一节------在此给出链表的基本操作
  • 「译」Node.js Streams 基础
  • 【笔记】你不知道的JS读书笔记——Promise
  • Akka系列(七):Actor持久化之Akka persistence
  • Electron入门介绍
  • idea + plantuml 画流程图
  • JavaScript创建对象的四种方式
  • Javascript弹出层-初探
  • Laravel Telescope:优雅的应用调试工具
  • LeetCode刷题——29. Divide Two Integers(Part 1靠自己)
  • Ruby 2.x 源代码分析:扩展 概述
  • UEditor初始化失败(实例已存在,但视图未渲染出来,单页化)
  • ViewService——一种保证客户端与服务端同步的方法
  • Web设计流程优化:网页效果图设计新思路
  • 阿里云ubuntu14.04 Nginx反向代理Nodejs
  • 安装python包到指定虚拟环境
  • 百度贴吧爬虫node+vue baidu_tieba_crawler
  • 深度学习入门:10门免费线上课程推荐
  • 正则表达式小结
  • 自动记录MySQL慢查询快照脚本
  • MPAndroidChart 教程:Y轴 YAxis
  • 微龛半导体获数千万Pre-A轮融资,投资方为国中创投 ...
  • ​Base64转换成图片,android studio build乱码,找不到okio.ByteString接腾讯人脸识别
  • ​一、什么是射频识别?二、射频识别系统组成及工作原理三、射频识别系统分类四、RFID与物联网​
  • !!Dom4j 学习笔记
  • ## 临床数据 两两比较 加显著性boxplot加显著性
  • #Linux(权限管理)
  • #考研#计算机文化知识1(局域网及网络互联)
  • #我与Java虚拟机的故事#连载04:一本让自己没面子的书
  • #我与Java虚拟机的故事#连载11: JVM学习之路
  • $var=htmlencode(“‘);alert(‘2“); 的个人理解
  • (pytorch进阶之路)扩散概率模型
  • (分享)自己整理的一些简单awk实用语句
  • (附源码)spring boot建达集团公司平台 毕业设计 141538
  • (附源码)springboot社区居家养老互助服务管理平台 毕业设计 062027
  • (十五)Flask覆写wsgi_app函数实现自定义中间件
  • (推荐)叮当——中文语音对话机器人
  • (转载)VS2010/MFC编程入门之三十四(菜单:VS2010菜单资源详解)
  • ***linux下安装xampp,XAMPP目录结构(阿里云安装xampp)
  • .desktop 桌面快捷_Linux桌面环境那么多,这几款优秀的任你选