石家庄网站建设哪里好,百度竞价推广开户,在哪个平台做网站好,网站平台建设费计入什么科目目录
TCP连接
TCP报文段结构
往返时间估计与超时
可靠数据传输
回退N步or超时重传
超时间隔加倍
快速重传
流量控制
TCP连接管理
三次握手
1. 客户端 → 服务器#xff1a;SYN 包
2. 服务器 → 客户端#xff1a;SYNACK 包
3. 客户端 → 服务器#xff1a;AC…目录
TCP连接
TCP报文段结构
往返时间估计与超时
可靠数据传输
回退N步or超时重传
超时间隔加倍
快速重传
流量控制
TCP连接管理
三次握手
1. 客户端 → 服务器SYN 包
2. 服务器 → 客户端SYNACK 包
3. 客户端 → 服务器ACK 包
四次挥手
1. 主动关闭方 → 被动关闭方FIN 包
2. 被动关闭方 → 主动关闭方ACK 包
3. 被动关闭方 → 主动关闭方FIN 包
4. 主动关闭方 → 被动关闭方ACK 包 为什么必须要三次握手
为什么不能用两次握手
四次或更多次握手可行吗
为什么要四次挥手
为什么不能用三次挥手
两次挥手可行吗 TCP是因特网运输层面向连接的可靠传输协议。为了提供可靠数据传输TCP依赖前文可靠数据传输原理 许多基本原理其中包括差错检测重传累积确认定时器以及用于序号和确认号的首部字段等。
TCP连接
TCP 被称为面向连接的协议核心在于其通信过程需要经历 “连接建立→数据传输→连接释放” 的完整生命周期。TCP 通信前必须通过三次报文交互在客户端和服务器之间协商并确认连接参数确保双方具备通信能力三次握手。通信结束后需通过四次报文交互主动释放连接资源确保双方无数据残留四次挥手。TCP 的 “面向连接” 本质是状态化通信连接是一种状态实体通信依赖连接状态的一致性错误的处理基于连接的上下文。
TCP连接提供的是全双工服务在一个 TCP 连接中通信双方客户端和服务器可以同时进行数据的发送和接收发送方和接收方的角色是动态的、非独占的。TCP 连接包含两条独立的逻辑通道两条通道的数据流互不干扰各自维护独立的序列号、确认号、滑动窗口等状态信息。
TCP被设计为点对点Point-to-Point协议而非一对多如组播或广播这是由其协议特性、设计目标和底层网络架构共同决定的。TCP 的核心定位是在两个端点之间建立一条逻辑连接通过序列号、确认机制、滑动窗口等复杂机制实现端到端的可靠数据传输。这些机制依赖于唯一的双向通信链路要求发送方和接收方之间有明确的一一对应关系。若支持一对多如同时向多个接收方发送数据每个接收方的网络状态、接收能力、数据确认逻辑均不同需为每个接收方单独维护一套状态如序号、窗口、超时定时器等这会导致协议复杂度呈指数级上升甚至无法高效管理。
TCP 将数据视为无边界的字节流保证数据按发送顺序到达接收方。在点对点场景中通过单一序列号空间即可实现顺序控制但在一对多场景中每个接收方的字节流顺序独立发送方需为每个接收方维护独立的序列号和确认逻辑这与 TCP 的字节流抽象模型冲突。且一对多属于网络层或应用层的职责而TCP 专注于传输层的端到端可靠性。 应用进程将数据写入套接字后会先存于 TCP 发送缓存等待合适时机发送数据暂存。发送缓存配合滑动窗口机制根据接收方通告的窗口大小控制发送数据量。若接收方接收缓存快满通告小窗口值发送方就减少从发送缓存提取数据发送的量避免数据丢失流量控制。发送缓存中未被确认的数据在超时未收到确认时会重传可靠传输保证。
TCP 报文段TCP Segment是 TCP在网络中传输数据的基本单位它由首部和数据部分 组成承载着从发送端到接收端的数据以及用于实现可靠传输的控制信息。
TCP接收方将网络中传来的 TCP 报文段经解析后数据存于接收缓存供应用进程读取数据接收缓存。当收到乱序的报文段只要序号在接收窗口内就暂存于接收缓存等待正确顺序时交付应用进程乱序处理。接收缓存剩余空间大小决定接收方通告给发送方的窗口大小以此反馈控制发送方发送速率流量反馈依据。
TCP可从缓存中取出并且放入报文段的数据数量受限于最大报文段长度MSS。MSS 指的是 TCP 报文段中所能承载的应用层数据的最大字节数不包括 TCP 首部通常 20 字节 和 IP 首部通常 20 字节 。MSS通常根据最初确定的由本地发送主机发送的最大链路层帧长度即所谓的最大传输单元MTU来设置。
MTU 指的是在数据链路层中一个数据帧所能够携带的最大有效载荷不包含帧头、帧尾等链路层控制信息的字节数。不同的数据链路层协议MTU 的默认值有所不同 。比如以太网的 MTU 默认值是 1500 字节PPP 协议的 MTU 默认值通常为 1500 字节或 296 字节FDDI光纤分布式数据接口的 MTU 则为 4352 字节。
比如若 MSS 值为 1460 字节那么加上 20 字节的 TCP 首部和 20 字节的 IP 首部后整个 IP 数据报长度就是 1500 字节这恰好是以太网默认的最大传输单元MTU。
TCP报文段结构 TCP 报文段首部长度通常为 20 字节不含TCP可选字段最多可达 60 字节包含了实现可靠传输、连接管理等功能的关键控制信息具体如下
源端口号和目的端口号各占 16 比特标识发送方和接收方应用进程所使用的端口帮助数据准确交付给对应的应用程序。序号占 32 比特标记本报文段在发送方数据字节流中的位置用于接收方对数据进行排序。确认号占 32 比特是接收方期望接收的下一个字节的序号用于向发送方确认已收到的数据。首部长度占 4 比特指示 TCP 首部的长度以 4 字节为单位用于明确首部结束和数据开始的位置。标志位占 6 比特包含多个标志 URG紧急标志URG 1 时表示报文中有紧急数据。ACK确认标志ACK 1 时确认号字段才有效。PSH推送标志指示接收方尽快将数据交付给上层应用。RST重置标志用于异常时重置连接。SYN同步标志在连接建立时同步序号。FIN结束标志在连接释放时通知对方本方无数据发送。 窗口大小占 16 比特接收方通过该字段告知发送方自己当前接收缓冲区的剩余空间大小实现流量控制。校验和占 16 比特用于检测 TCP 报文段在传输过程中是否出错计算范围包括首部、数据部分以及一个伪首部。紧急指针占 16 比特当 URG 标志位为 1 时有效指出本报文段中紧急数据的最后一个字节的序号。选项长度可变最多 40 字节用于协商额外参数如最大段大小MSS、窗口扩大因子、时间戳等 。数据部分承载的是应用层实际要传输的数据长度可变受最大段大小MSS限制。在连接建立阶段客户端和服务器会协商 MSS 值以确保加上 IP 首部后的整个报文长度不超过链路层的最大传输单元MTU避免 IP 分片。
在 TCP 报文段结构中序号和确认号是实现可靠传输最核心的两个字段。
TCP把数据看成无结构的有序的字节流。序号是建立在传送的字节流之上而不是建立在传送的报文段序列之上。因此一个报文段的序号就是该报文段首字节的字节流编号。 序号标识本报文段所携带数据在发送方字节流中的起始位置用于解决数据分片后的排序问题。例如若发送方发送的第一个报文段携带 1000 字节数据序号为500则下一个报文段的序号为1500。接收方通过序号判断数据是否按序到达对乱序数据进行缓存或重传请求。在连接建立三次握手时序号用于同步初始序列号ISN避免历史数据干扰新连接。
接收方通过确认号告知发送方期望接收的下一个字节的序号表示 “该序号之前的数据已全部正确接收”。例如接收方收到序号1-1000的数据后会返回确认号1001表示希望接收1001及之后的数据。发送方根据确认号判断哪些数据已被成功接收哪些需要重传基于超时重传机制。同时实现可靠传输的双向确认不仅发送方需要确认接收方收到数据接收方也通过确认号主动告知发送方状态。
TCP 通过 “序号 确认号” 机制实现数据的有序性、完整性和去重性是可靠传输的基础其他字段均围绕二者提供辅助或扩展功能。
往返时间估计与超时
显然由于路由器的拥塞和端系统负载的变化TCP报文段中的rtt值也会随之波动所以任何给定的RTT值也许不是典型的所以这也造就了一个明显的问题设置超时间隔的长度。因此为了估计一个典型的RTT自然要对RTT进行一个均值操作。 TCP 采用一种基于采样的方法来估计 RTT。最初TCP 会对每个发送的报文段进行计时当收到对应的 ACK 时计算实际的往返时间。然后通过加权平均的方式更新对 RTT 的估计值一旦获得一个新的RTT,TCP就会用以下公式更新均值
其中α是一个加权因子通常取值在 0.125 左右 SampleRTT是当前测量得到的样本往返时间。
除了估算RTT以外测量RTT的变化也是很有必要的。DEVrtt用于衡量往返时间估计值的波动情况是计算超时时间的重要参数之一。 其中β也是一个加权因子一般取值为 0.25。该公式的作用是计算往返时间估计值的偏差。|SampleRTT - EstimatedRTT| 表示样本往返时间与估计往返时间的差值的绝对值通过加权平均的方式更新 DEVrtt 从而反映出样本往返时间围绕估计往返时间的波动程度。
既然已经给出了EstimateRTT和DevRTT的值TCP 的超时间隔Timeout Interval简称 RTO通常使用 其中δ 是一个经验系数 该系数用于放大 EstimatedRTT 的权重确保超时间隔足够覆盖网络波动。 4 是 δ 的典型取值通过将偏差放大 4 倍使 RTO 对网络延迟的波动更敏感。
可靠数据传输
在 TCP 协议中定时器的设置是保障可靠传输的关键机制之一。TCP 使用多种定时器来处理不同场景其中最核心的是超时重传定时器。
TCP采用的是单计时器模型发送方每次发送 新数据 时若当前没有活跃的定时器则启动一个覆盖 最早未确认数据 的定时器。当收到 最早未确认数据的 ACK 时停止定时器。
第二个主要事件是超时处理TCP通过超时重传来响应超时事件然后重启定时器。 回退N步or超时重传
TCP 的可靠性机制部分借鉴了 GBN 和 SR 的思想根据自身需求进行了优化和融合。
TCP使用滑动窗口机制但 默认采用累积确认与 GBN 类似TCP 的滑动窗口大小可变动态调整而 GBN 窗口大小固定。TCP同样为未确认的数据设置定时器超时后重传 最早未确认的分组及之后的数据类似 GBN 的回退重传。但是TCP 引入 快速重传机制减少不必要的超时等待。
TCP引入 选择性确认SACK选项类似SR作为累积确认的补充。当接收方收到失序分组时可通过 SACK 告知发送方具体哪些分段已接收发送方只需重传未被确认的分段。但SACK 是 TCP 的可选功能需双方协商启用而累积确认是默认机制。接收方同样会缓存失序分组通过接收窗口实现并在收到丢失分组后按序交付。
超时间隔加倍
在 TCP 协议中超时间隔加倍Exponential Backoff 是一种应对网络拥塞或丢包的重要机制属于超时重传策略的一部分。当 TCP 发送方多次尝试重传数据仍失败时会逐步指数级增大超时时间避免因频繁重传加剧网络拥塞。
当 TCP 发送一个报文段后会启动一个定时器。若在 RTO 时间内未收到该报文段的确认ACK则认为报文段丢失触发重传。
首次超时按正常 RTO 值重传后续超时每次重传后将 RTO 值翻倍即指数级增长。为避免 RTO 无限增长TCP 通常设置上限如 64 秒。当 RTO 达到上限后继续重传但不再增加 RTO。
超时间隔加倍避免网络拥塞若每次超时都以固定时间重传可能导致大量重传报文段同时涌入网络加剧拥塞如 “拥塞崩溃”。指数退避通过减缓重传频率给网络留出恢复时间。
区分临时丢包和持续问题
临时丢包如网络抖动较小的 RTO 即可快速恢复。持续丢包如链路故障需要更长的 RTO 避免无效重传。
超时重传 → RTO指数级增长 → 降低重传频率 → 缓解网络拥塞 这一机制是 TCP自适应网络变化的关键通过动态调整超时时间在可靠性和效率之间找到平衡尤其适用于高延迟或不稳定的网络环境。
快速重传
快速重传是 TCP 协议中用于快速恢复丢失报文段的机制乱序不影响最终确认但是会触发重传机制。通过 重复确认冗余ACKDuplicate ACK 触发重传无需等待超时定时器到期从而减少丢包导致的延迟。
接收方通过累加确认只会确认按序到达的连续字节流末尾未按序到达的字节会导致后续确认被阻断。
当接收方收到失序报文段时会发送重复 ACK即对最近连续收到的最高序号的确认。发送方收到3 个重复 ACK判定该序号的报文段丢失立即重传无需等待超时。
快速重传 3次重复ACK触发 立即重传丢失报文段 低延迟恢复传输 该机制是 TCP 实现可靠传输和高吞吐量的核心技术之一通过快速响应轻度丢包显著提升了网络传输效率尤其适用于实时性要求较高的场景。
流量控制
TCP流量控制为了防止发送方发送速率超过接收方处理能力避免接收方缓冲区溢出导致丢包。通过动态调整发送窗口大小使发送速率与接收方处理能力匹配。
核心机制滑动窗口协议 接收窗口Advertised Window, rwnd 接收方通过 ACK 报文携带rwnd字段告知发送方自己当前可用的接收缓冲区大小字节。计算公式rwnd 接收缓冲区总大小 - 已占用空间。 发送窗口Send Window 发送方根据接收方的rwnd动态调整自己的发送窗口大小确保已发送但未确认的数据量 ≤ rwnd。发送窗口大小 min (rwnd, cwnd)其中cwnd为拥塞窗口由拥塞控制决定。 初始协商连接建立时双方通过 SYN 报文交换初始窗口大小默认值通常为 4KB。
动态调整接收方每处理一批数据通过 ACK 报文更新rwnd。发送方根据最新rwnd调整发送窗口控制后续发送速率。
零窗口通知当接收方缓冲区已满rwnd 0发送方暂停发送进入 ** 窗口探查Window Probe** 状态。
窗口探查发送方定期发送窗口探测报文1 字节数据触发接收方回复最新rwnd避免死锁。
该机制通过接收窗口实现端到端的速率匹配确保接收方不会因过载而丢包。UDP没有流量控制报文段由于缓存溢出可能在接收方丢失。
TCP连接管理
我们先来详细看一下客户端如何三次握手和服务器建立TCP连接以及四次挥手安全断开连接
三次握手
1. 客户端 → 服务器SYN 包
动作 客户端向服务器发送一个SYN 包TCP 首部中的 SYN 标志位 1表示请求建立连接。携带信息 初始序列号ISN, Initial Sequence Number客户端随机生成的一个 32 位序列号如x用于标识客户端发送的数据字节流起点。可选参数如最大段大小MSS、窗口缩放因子等。 状态变化 客户端进入SYN_SENT状态等待服务器响应。
2. 服务器 → 客户端SYNACK 包
动作 服务器收到 SYN同步 包后向客户端发送一个SYNACK 包SYN 和 ACK 标志位同时置 1。携带信息 服务器的初始序列号ISN服务器随机生成的序列号如y。确认号ACK Number值为x1表示 “已收到客户端的 SYN 包期望接收客户端下一个序列号为x1的数据”。窗口大小Window Size服务器的接收窗口大小告知客户端自己的缓冲区容量。 状态变化 服务器进入SYN_RCVD状态等待客户端确认。
3. 客户端 → 服务器ACK 包
动作 客户端收到 SYNACK 包后向服务器发送一个ACK 包ACK 标志位 1SYN0。携带信息 确认号值为y1表示 “已收到服务器的 SYN 包期望接收服务器下一个序列号为y1的数据”。序列号客户端使用x1作为本次 ACK 的序列号因 SYN 包本身占用一个序列号。 状态变化 客户端和服务器均进入ESTABLISHED状态连接建立完成开始数据传输。
四次挥手
1. 主动关闭方 → 被动关闭方FIN 包
场景 假设客户端主动发起关闭也可以是服务器主动关闭。动作 客户端向服务器发送一个FIN 包TCP 首部中的 FIN 标志位 1表示 “我已无数据要发送可以关闭连接”。携带信息 序列号Seq客户端当前的序列号uFIN 包本身占用一个序列号类似 SYN 包。 状态变化 客户端进入FIN_WAIT_1状态等待服务器的确认。
2. 被动关闭方 → 主动关闭方ACK 包
动作 服务器收到 FIN 包后立即向客户端发送一个ACK 包ACK 标志位 1表示 “已收到关闭请求正在处理剩余数据”。携带信息 确认号Ack值为u1表示 “已确认收到客户端的 FIN 包”。序列号Seq服务器当前的序列号v未被 FIN 中断继续沿用之前的序号。 状态变化 服务器进入CLOSE_WAIT状态半关闭状态此时服务器仍可向客户端发送剩余数据客户端仍需接收。 客户端收到 ACK 后进入FIN_WAIT_2状态等待服务器发送 FIN 包。
3. 被动关闭方 → 主动关闭方FIN 包
动作 当服务器确认已发送完所有数据后向客户端发送第二个FIN 包FIN 标志位 1表示 “我已无数据可发送正式请求关闭连接”。携带信息 序列号Seq服务器的下一个序列号w通常w v 已发送数据字节数若中间无新数据则w v。 状态变化 服务器进入LAST_ACK状态等待客户端的最终确认。 客户端收到第二个 FIN 后进入TIME_WAIT状态。
4. 主动关闭方 → 被动关闭方ACK 包
动作 客户端收到服务器的 FIN 包后向服务器发送最后一个ACK 包表示 “已确认关闭请求”。携带信息 确认号Ack值为w1确认服务器的 FIN 包。序列号Seq客户端的下一个序列号u1FIN_WAIT_2 状态时序列号未变化因无新数据发送。 状态变化 客户端发送 ACK 后进入TIME_WAIT状态并在等待2 倍最大段生存时间2MSL后最终进入CLOSED状态。服务器收到 ACK 后立即进入CLOSED状态连接彻底关闭。
客户TCP经历的典型TCP状态序列 服务器端TCP经历的典型TCP状态序列 为什么必须要三次握手
双向确认连接可用性 客户端确认服务器 “能接收数据 能发送数据”。服务器确认客户端 “能接收数据 能发送数据”。 同步初始序列号Seq 避免历史残留报文延迟到达的旧连接数据包干扰新连接。
为什么不能用两次握手
假设改为两次握手客户端→服务器SYN服务器→客户端SYNACK 存在的风险
旧连接残留报文导致的资源浪费 客户端发送的旧 SYN 报文如因网络延迟滞留被服务器误认为是新连接请求。服务器返回 SYNACK 并分配资源但客户端实际未发起新连接导致服务器端资源如连接队列、内存浪费“半开连接” 问题。 单向确认不完整 服务器仅能确认客户端 “能发送数据”但无法确认客户端 “能接收数据”。若客户端实际无法接收如接收缓冲区已满服务器发送的数据会被丢弃导致连接不可靠。
结论两次握手无法避免旧报文干扰且无法完成双向确认因此不可行。
四次或更多次握手可行吗
理论上可行但存在明显缺陷
效率低下 每增加一次握手就多一次往返时延RTT。例如四次握手需 2 倍 RTT而三次握手仅需 1.5 倍 RTT对于高延迟网络如卫星通信效率损失显著。无额外收益 三次握手已能完成双向确认和序列号同步多余的握手次数不会提升可靠性反而增加协议复杂度。
结论三次握手是效率与可靠性的最优平衡多于三次握手无实际意义。 为什么要四次挥手
TCP 连接是全双工的双向独立传输全双工特性要求双向数据流独立关闭
允许双向数据流独立关闭 一方如客户端先发送 FIN 包请求关闭 “主动关闭方→被动关闭方” 的数据流另一方仍可继续发送数据。确保数据完整传输 被动关闭方需先确认收到 FIN 包避免丢包待自身数据发送完毕后再发送 FIN 包关闭反向数据流确保无数据丢失。
为什么不能用三次挥手
假设尝试合并两次挥手为一次如服务器在 ACK 包中同时携带 FIN 标志 存在的问题
被动关闭方可能尚未完成数据发送 服务器收到客户端的 FIN 包后需先确认ACK但此时服务器可能仍有数据未发送完毕。若直接在 ACK 中携带 FIN会导致服务器被迫中断数据传输违反 “允许单向数据流持续” 的原则。
示例场景 客户端发送 FIN 请求关闭 “客户端→服务器” 方向服务器回复 ACK确认收到 FIN并继续发送剩余数据。待数据发送完毕后服务器再发送 FIN 关闭 “服务器→客户端” 方向。这一过程必须分为两次独立的报文ACK 和 FIN因此无法合并为三次挥手。
两次挥手可行吗
仅在一种特殊场景下可行被动关闭方在收到 FIN 包时自身已无数据需要发送。此时可将 ACK 和 FIN 合并为一个报文形成两次挥手
客户端→服务器FIN请求关闭。服务器→客户端FINACK确认关闭并请求反向关闭。客户端→服务器ACK确认反向关闭。 但这是特例而非通用情况因为 TCP 无法保证被动关闭方在收到 FIN 时恰好无数据待发。
结论通用场景下必须四次挥手仅特殊场景可简化为三次但无法普遍适用两次。 ✍✍✍.