目录一UDP1.UDP协议端格式2.UDP的特点二TCP1.TCP协议段格式2.确认应答机制1.确认应答的原理2.为什么有两个序号——捎带应答3.超时重传4.快速重传3.连接管理机制1.三次握手2.四次挥手shutdown函数COLSE_WAIT状态TIME_WAIT状态4.滑动窗口1.滑动窗口是什么2.拥塞控制一UDP1.UDP协议端格式目的端口号Destination Port接收方主机收到 UDP 报文后根据这个端口号决定把数据交给哪个应用程序处理。 比如DNS 常用 53、TFTP 常用 69、QUIC 常用 443 等。源端口号Source Port标识发送方自己是哪个程序发出的数据。一般由操作系统随机分配方便对方收到数据后按这个端口原路回复给你。16 位 UDP 长度UDP Length表示整个 UDP 数据报的总字节长度 UDP 固定头部8 字节 数据部分 16 位所以取值范围8 65535 字节64KB16 位 UDP 校验和UDP Checksum校验和不一致认为传输出错直接丢弃不重传、不纠错2.UDP的特点⽆连接: 知道对端的IP和端⼝号就直接进⾏传输,不需要建⽴连接;不可靠: 没有确认机制,没有重传机制;如果因为⽹络故障该段⽆法发到对⽅,UDP协议层也不会给 应⽤层返回任何错误信息;⾯向数据报: 不能够灵活的控制读写数据的次数和数量;二TCP1.TCP协议段格式源/目的端口号:表⽰数据是从哪个进程来,到哪个进程去;32位序号/32位确认号:序号和确认序号可以同时存在序号保证数据有序交付确认序号累计确认已接收的数据触发发送方重传未确认数据4位TCP报头长度[0 - 15]乘以一个单位规定是4字节等于报头的长度[0 - 60]字节。所以一个报头的长度范围是[20 -60]字节。6位标志位SYNSynchronize发起连接请求或响应典型用于三次握手前两次把携带SYN标识的称为同步报文段ACKAcknowledgment确认已接收数据 / 控制信息使确认序号生效FINFinish发起正常关闭连接释放发送方的发送权核心用于四次挥手称携带FIN标识的为结束报文段RSTReset复位异常连接强制关闭处理连接超时、端口未监听、协议错误等场景把携带RST标识的称为复位报文段PSHPush推送数据要求接收方立即递交给应用层不缓存适用于键盘输入、聊天消息等实时数据传输URGUrgent标识段中包含紧急数据需优先处理需配合 “紧急指针” 字段使用。紧急指针字段会指向紧急数据的最后一个字节的下一位16 位窗口字段自己的接收缓冲区还剩余多少可用空间6位校验和:发送端填充,CRC校验.接收端校验不通过,则认为数据有问题.此处的检验和不光包含 TCP⾸部,也包含TCP数据部分.16位紧急指针:标识哪部分数据是紧急数据;2.确认应答机制1.确认应答的原理怎么保证我们发送的报文被对方收到了 ——对方收到报文后返回确认应答我们收到确认应答就可以保证之前的数据成功被对方接收了TCP将每个字节的数据都进行了编号.即为32位序号SEQTCP 报文段头部的 SEQ 字段代表的是该报文段携带的第一个数据字节的序号。ISNTCP 连接刚建立时双方各自随机选的第一个 “字节编号”就是 ISN。为了安全ISN 是系统随机生成的安全层面防止攻击者轻易猜到序列号实施 TCP 会话劫持、伪造恶意报文等攻击可靠性层面避免历史连接的重复报文被新建立的同四元组源 IP、源端口、目的 IP、目的端口连接错误接收造成数据错乱。双方各有一个 ISN客户端第一次握手发的seq x→ 客户端的 ISN服务器第二次握手发的seq y→ 服务器的 ISNTCP 的确认应答不是对单个报文段的确认而是对连续字节流的累计确认这是机制的核心设计。接收方回传的 ACK 报文中的确认号有严格的定义确认号 接收方已经成功、连续接收的最后一个字节的序号 1含义「确认号 - 1」及之前的所有字节已全部成功接收接下来期望收到的第一个字节的序号就是该确认号。举个完整的基础示例发送方发送 SEQ1001、数据长度 1000 字节的报文覆盖 1001~2000接收方成功收到该报文回传 ACK 报文其中ACK 号 2001发送方收到 ACK2001即可确认 1001~2000 的所有字节已成功交付无需再关注这段数据。累计确认的核心优势一个 ACK 可以确认连续的多个报文段无需为每个报文单独回 ACK大幅减少网络开销强制要求只有连续的字节被完整接收才会推进确认号从根本上解决乱序问题。2.为什么有两个序号——捎带应答为了减少网络中的纯 ACK 报文数量提升传输效率TCP 规范定义了两个优化规则延迟 ACK接收方不会对每个报文都立刻回 ACK而是等待最多 200ms若这段时间内有反向数据要发送给对端就将 ACK 确认号捎带在反向数据报文的 TCP 头部中一起发送无需单独发 ACK 包——既是对上一个接收报文的确认又是一个发送报文所以既有序号又有确认序号。强制立即 ACK遇到乱序报文、重复报文、丢包后补传的报文等异常场景接收方会立即发送 ACK不触发延迟让发送方尽快感知网络状态及时调整传输策略。3.超时重传如果发送的报文丢失或者ACK丢失怎么办呢发送方每发出一个报文段就会启动一个重传计时器RTORetransmission TimeOutRTO 的超时时间基于网络往返时延RTT动态计算适配网络波动。若 RTO 超时后仍未收到对应 ACK发送方判定该报文段丢失立即重传该报文段并重置计时器再次等待 ACK直到收到对应 ACK 为止。累计到⼀定的重传次数,TCP认为⽹络或者对端主机出现异常,强制关闭连接.4.快速重传连续收到 3 个重复 ACK不等超时就立刻重传速度更快。3.连接管理机制1.三次握手三次握手的核心目的让通信双方客户端 服务器互相确认自己的发送 / 接收能力正常、对方的发送 / 接收能力正常并同步双方的初始序列号ISN。两次握手无法完成双向收发能力的全验证为什么不是四次握手第二次握手中服务器的 ACK确认客户端请求和 SYN同步自身序列号可以合并在一个报文中发送没有必要拆分成两个独立报文2.四次挥手四次挥手的核心目的双方各自独立关闭自己的发送通道互相确认对方的关闭请求确保所有数据都传输完毕安全、完整地断开连接。为什么是 4 次不能是 3 次TCP 连接的两个传输方向是完全独立的。一方关闭自己的「发送通道」发 FIN 报文仅代表自己不再发送新数据但依然可以接收对方发来的数据直到对方也关闭发送通道。shutdown函数#include sys/socket.h int shutdown(int sockfd, int how);sockfdTCP 连接的套接字文件描述符how关闭方式参数宏定义数值作用TCP 通道控制关键行为SHUT_RD0关闭读通道无法再接收数据内核丢弃缓冲区数据发送通道正常SHUT_WR1关闭写通道本方不再发送数据主动发送 FIN 报文触发四次挥手第一次挥手仍可以接收对方数据SHUT_RDWR2关闭读写双通道同时关闭读写等价于先 SHUT_RD 再 SHUT_WR发送 FINCOLSE_WAIT状态server不关闭fdclient断开后就会一直处于CLOSE_WAIT状态导致文件描述符一直被占用内存泄漏等问题。TIME_WAIT状态TIME_WAIT 是TCP 主动关闭连接的一方在发送完第四次挥手的 ACK 报文后进入的一种等待状态核心作用① 保证第四次挥手的 ACK 能被对方收到主动方发完 ACK 后不直接关闭等待 2MSLMSL单个报文在网络中能存活的最大时间若服务端没收到 ACK会超时重传 FIN主动方在 TIME_WAIT 期间收到重传的 FIN会重新发送 ACK确保服务端能顺利从 LAST_ACK → CLOSED释放资源② 防止旧连接的延迟报文干扰新连接网络中可能存在延迟、迷路的旧报文如果主动方立刻关闭并新建相同四元组源 IP 端口、目的 IP 端口的连接旧报文可能会被新连接错误接收导致数据错乱TIME_WAIT 期间不能重新bind相同端口可以使用setsockopt()函数允许地址复用4.滑动窗口1.滑动窗口是什么窗口大小指的是⽆需等待确认应答而可以继续发送数据的最大值.上图的窗口大小就是4000个字节(四个段)发送前四个段的时候,不需要等待任何ACK,直接发送;收到第⼀个ACK后,滑动窗口向后移动,继续发送第五个段的数据;依次类推;操作系统内核为了维护这个滑动窗口,需要开辟发送缓冲区来记录当前还有哪些数据没有应答;只有确认应答过的数据,才能从缓冲区删掉;窗口越⼤,则⽹络的吞吐率就越高;滑动窗口把发送缓冲区分为了三部分a.已发送且被确认的部分窗口外左侧b.可以直接发送的部分,包含已发送但未被确认的部分窗口内c.不能发送的部分窗口外右侧那么滑动窗口的大小该如何决定呢窗口大小 min (拥塞窗口cwnd,接收窗口rwnd)接收窗口rwnd大小为tcp报文中的窗口大小字段下面介绍拥塞窗口cwnd2.拥塞控制拥塞窗口(cwnd)发送方自己维护代表网络能承受的最大发送量单位通常是 MSS一个报文最大数据量。慢启动门限 ssthresh阈值用来区分「慢启动阶段」和「拥塞避免阶段」1. 慢启动刚建立 TCP 连接时不知道网络好坏cwnd 初始很小一般从 1 个 MSS 开始。规则每收到 1 个 ACKcwnd 翻倍指数增长1→2→4→8→16…目的快速试探网络能承受多大流量不一开始就猛发。退出条件cwnd 增长到 ≥ ssthresh切换到拥塞避免。2. 拥塞避免不再指数暴涨改为线性缓慢增长。规则每经过一个往返时间 RTTcwnd 1目的慢慢逼近网络极限避免突然拥塞。触发场景ssthresh 变化cwnd 变化后续阶段拥塞判定等级超时重传当前 cwnd/2直接重置为初始值1/10 个 MSS重新进入慢启动严重拥塞链路大概率不通 / 大面积丢包3 次重复 ACK 快速重传当前cwnd/2先设为新的 ssthresh后续线性增长进入快速恢复→拥塞避免轻度拥塞仅个别报文丢包链路通畅