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

TCP 连接管理 之 三次握手详解

TCP 连接管理 之 三次握手详解

(一)TCP三次握手详细过程及状态变化

1. 第一次握手(客户端 → 服务器)
  • 报文标志位SYN=1(同步序列号),ACK=0(首次握手无确认)
  • 序列号:客户端随机生成初始序列号(例如 seq=x
  • 过程:客户端发送SYN报文,进入SYN_SENT状态
  • 状态变化
    • 客户端:CLOSEDSYN_SENT
    • 服务器:LISTEN(等待连接)
2. 第二次握手(服务器 → 客户端)
  • 报文标志位SYN=1ACK=1(确认客户端的SYN)
  • 序列号:服务器随机生成初始序列号(例如 seq=y),确认号为 ack=x+1(第一次握手不携带数据,但SYN=1会消耗一个序列号)
  • 过程:服务器发送SYN+ACK报文,进入SYN_RCVD状态
  • 状态变化
    • 服务器:LISTENSYN_RCVD
    • 客户端:保持SYN_SENT
3. 第三次握手(客户端 → 服务器)
  • 报文标志位ACK=1SYN=0(非同步)
  • 序列号seq=x+1(收到的确认号),确认号为 ack=y+1(第二次握手不携带数据,但SYN=1会消耗一个序列号)
  • 过程:客户端发送ACK报文,双方进入ESTABLISHED状态
  • 状态变化
    • 客户端:SYN_SENTESTABLISHED
    • 服务器:SYN_RCVDESTABLISHED

(二)连接建立后数据传输的序列号规则

1. 客户端先发送数据
  • 客户端发送数据
    • seq=x+1(第三次握手没有数据部分,沿用第三次握手的序列号)
    • ack=y+1(保持对服务器序列号的确认)
  • 服务器响应ACK
    • seq=y+1(服务器初始序列号+1)
    • ack=x+1+数据长度(确认客户端数据)
2. 服务器先推送数据
  • 服务器发送数据
    • seq=y+1(握手最后使用的序列号)
    • ack=x+1(第三次握手没有数据部分,保持对客户端序列号的确认)
  • 客户端响应ACK
    • seq=x+1(客户端初始序列号+1)
    • ack=y+1+数据长度(确认服务器数据)
3. 关键点总结
  1. 初始序列号:双方随机生成,防止历史连接冲突。
  2. ACK确认机制:总是对已接收数据长度+1进行确认(期待下一个字节的序列号)。
  3. 数据传输:先发送数据的一方使用自己最后一次ACK的序列号作为起始值。

(三)TCP三次握手服务端资源建立的详细过程

1. 服务端内核在第一次握手(收到客户端的SYN报文)时为客户端生成套接字
2. 详细过程分析

① 第一次握手前(服务端状态:LISTEN

  • 服务端调用listen()后,进入LISTEN状态,此时仅有一个监听套接字(Listening Socket),用于接收所有客户端的连接请求。
  • 监听套接字不直接关联具体客户端,而是等待SYN报文触发新连接。

② 第一次握手(客户端发送SYN,服务端收到)

  • 内核动作
    当服务端内核收到客户端的SYN报文(标志位SYN=1)时,会立即创建一个普通套接字(Socket),称为未完成连接套接字(Incomplete Connection Socket),并进入SYN_RCVD状态。

    该套接字记录客户端的IP、端口、初始序列号(client_isn)等信息。
    此时套接字尚未完全建立(未通过第三次握手),但已占用资源(进入了半连接队列)。

  • 为什么此时生成?

    资源预留:为防止SYN Flood攻击,内核需要限制半连接队列大小(net.ipv4.tcp_max_syn_backlog)。
    状态跟踪:服务端需维护客户端的seq和连接状态,以完成后续握手。

③ 第二次握手(服务端发送SYN+ACK

  • 服务端使用新生成的套接字发送SYN+ACKseq=server_isn, ack=client_isn+1),但仍处于SYN_RCVD状态。
  • 此时套接字仍在半连接队列中,等待客户端的最终ACK

④ 第三次握手(客户端发送ACK,连接完成)

  • 服务端收到ACK后,将套接字从半连接队列移到全连接队列(Accept Queue),状态变为ESTABLISHED
  • 当服务端应用调用accept()时,从全连接队列中取出该套接字,交给应用程序使用。
3. 总结
阶段服务端动作套接字状态
第一次握手前仅有监听套接字(LISTEN无客户端套接字
第一次握手收到SYN后,内核生成新套接字半连接队列(SYN_RCVD
第三次握手后套接字移至全连接队列,等待accept()可用的ESTABLISHED套接字

① 为什么不在第三次握手后再生成套接字?

  • 如果在第三次握手后才生成,服务端无法在第二次握手时发送SYN+ACK(需要记录客户端信息)。
  • 提前生成可确保资源分配和状态跟踪,但需防范SYN Flood攻击(通过半连接队列限制)。

② 半连接队列 vs 全连接队列

  • 半连接队列(SYN Queue):存储未完成三次握手的套接字(SYN_RCVD状态),队列大小由net.ipv4.tcp_max_syn_backlog参数决定。
  • 全连接队列(Accept Queue):存储已完成握手但未被accept()的套接字(ESTABLISHED状态),队列大小由backlog参数和net.core.somaxconn决定。

③ 如果第三次握手的ACK丢失怎么办?

  • 服务端会重传SYN+ACK(次数由net.ipv4.tcp_synack_retries控制),超时后删除半连接套接字。
http://www.dtcms.com/a/307957.html

相关文章:

  • 在Trae中使用MoonBit月兔1 创建项目
  • 力扣-102. 二叉树的层序遍历
  • 【BUG】nvm无法安装低版本Node.js:The system cannot find the file specified解决方案
  • 关于npm前端项目编译时栈溢出 Maximum call stack size exceeded的处理方案
  • 去重、top_n()、pull()、格式化
  • LCM中间件入门(1):工作原理核心概念及Ubuntu环境下的C++实践
  • 如何在NPM上发布自己的React组件(包)
  • 基于岗位需求的康养休闲旅游服务实训室建设方案
  • 达梦(DM8)常用管理SQL命令(3)
  • JavaScript内存管理完全指南:从入门到精通(通俗版+硬核版)
  • python后端之DRF框架(下篇)
  • Linux 服务器性能优化:性能监控,系统性能调优,进程优先级,内核升级全解析
  • 常见的中间件漏洞(tomcat,weblogic,jboss,apache)
  • 制造业企业如何保障文件外发图纸数据安全的?
  • dubbo源码之消费端启动的高性能优化方案
  • CTE公用表表达式的可读性与性能优化
  • Java项目:基于SSM框架实现的小区物业管理系统【ssm+B/S架构+源码+数据库+毕业论文+开题报告+任务书+远程部署】
  • 解决Git升级后出现的问题
  • DeepSeek SEO关键词优化提升流量增长
  • Linux Shell 条件判断:`test`、`[`、`[[` 命令深度解析
  • centos yum更换阿里源
  • 处理vscode在Ubuntu18.04上用不到的方法
  • 【大模型理论篇】跨语言AdaCOT
  • 关于PHP学习
  • 飞算科技:以自主创新引领数字科技浪潮,飞算JavaAI赋能产业智能化升级
  • 亚远景-ASPICE与ISO 26262评估标准:异同解析与协同实践
  • Linux基础练习题1
  • 谷歌正在美国测试一项基于机器学习的年龄识别技术
  • 前端技术栈详解
  • 【人工智能-15】OpenCV直方图均衡化,模板匹配,霍夫变换,图像亮度变换,形态学变换