资讯动态

传输层详解:从端口到TCP/UDP,可靠传输与连接管理实战

发布时间:2026/10/20 22:00:38 来源:尧图企业网站定制
先说个我经常对新人说的话学了 IP 地址不等于懂网络。IP 能解决的问题是“把数据送到某台主机”但数据到了主机之后该交给哪个进程浏览器发的请求和后台服务发的数据报会不会互相串数据在半路丢了谁来管顺序乱了谁来重排这些问题全部落在传输层肩上。这篇是我计算机网络系列笔记的第五篇专门把传输层讲透。内容覆盖端口与套接字、UDP 和 TCP 的差异、可靠传输的机制、流量控制、拥塞控制、连接管理以及我用 Wireshark 抓包验证这些机制的实操过程。适合刚学网络的同学、准备面试的开发者以及那些线上出现网络问题却不知道从哪入手的运维朋友。1. 为什么需要传输层从“主机能通”到“进程能通话”看每一层协议最好先问一句上一层已经解决了什么问题这一层又在解决什么新的问题只有把这个问题想清楚后面记再多的状态机、标志位才不是死记硬背。1.1 网络层的边界只负责把包送到主机网络层IP提供的是主机到主机的通信而且是尽力而为的通信。IP 协议负责寻址和路由它能把数据报从一台主机送到另一台主机但有三件事它不管第一不保证数据包不丢失路由器队列满了直接丢源主机根本不知道第二不保证顺序同一个连接的数据包走不同路径到达完全可能后发先至第三不保证不重复有些链路层机制会导致重复帧IP 层不会去重。更重要的一点是IP 层不存在“端口”这个概念。IP 头里的地址是给路由器看的路由器根据目的 IP 转发它不关心、也不需要关心这个包是 HTTP 还是 DNS是游戏数据还是视频流。也就是说网络层把信送到了“公司前台”但前台不知道信是给技术部还是财务部。1.2 传输层补上的两块拼图复用/分用与逻辑通信传输层补的第一块拼图是端口号。一台主机上同时跑着几十个进程浏览器、邮件客户端、后台服务各占一个端口。发送方把源端口和目的端口写进传输层首部数据到达主机后系统根据目的端口号把数据交给对应的进程。多个进程的应用数据复用到同一个 IP 网络传输叫复用接收端再按端口拆开分给不同进程叫分用。这一下通信的粒度就从“主机”细化到了“进程”。第二块拼图是逻辑通信。应用进程之间通信时TCP 会给上层提供一种“像有一条专线连着对方”的错觉数据丢了自动重传数据乱序自动排序接收方处理不过来时发送方会自动减速。应用完全看不到底层网络抖动带来的丢包和乱序。当然这是 TCP 提供的服务UDP 不提供这些但 UDP 至少也提供端口复用和差错检测。我理解传输层最常用的一个类比是物流网络层只负责把包裹从这个城市运到那个城市至于这个包裹是给小区里哪栋楼哪户人家以及运送途中保价不保价、丢件赔不赔都是传输层的事。你要普通快递还是保价快递对应 UDP 和 TCP 的区别。1.3 为什么非得是“层”而不是把端口塞进 IP 头里有人会问既然端口这么重要为什么不直接把它加进 IP 首部省得单独分一层答案要从职责边界和扩展性来看。IP 层要解决的是全球寻址问题它被运行在网络里每一台路由器上。如果 IP 头里加端口意味着所有转发节点都要理解端口语义协议复杂度会急剧膨胀。而且传输层不是只有一种选择——有的应用需要可靠有序有的应用只在意低延迟。把这些差异放到 IP 之上用不同传输层协议承载网络层就只需要关心“把包从 A 送到 B”技术演进也灵活得多。你看 QUIC 直接在 UDP 之上重新实现了可靠传输和拥塞控制IP 层完全不需要改动这就是分层带来的好处。2. 端口与套接字定位一条连接的唯一坐标传输层所有机制的落点都可以归结到一个问题上怎么在茫茫网络里唯一确定一条通信关系。答案就是端口和套接字。2.1 端口号的地盘划分知名、注册与动态端口号是 16 位无符号整数范围 0 到 65535。这个范围被分成了三段范围类型说明常见例子0-1023知名端口由系统服务使用一般需要管理员权限才能绑定HTTP 80、HTTPS 443、DNS 53、SSH 221024-49151注册端口给用户进程或常见应用使用MySQL 3306、Redis 6379、MongoDB 2701749152-65535动态/私有端口客户端发起连接时由系统临时分配出站连接的源端口这里面有个应用层常识服务端的端口要固定不然客户端不知道找谁客户端的端口是临时的每次发起连接时系统从动态范围内挑一个空闲的。服务器监听 80进来的新连接可能是从客户端 50000 端口发起的所以服务端的通信对象实际上是“远端 IP 远端端口”的组合。如果绑定知名端口时报错“Permission denied”不是端口被占用而是权限不足普通用户端口范围不是所有系统都允许绑定 1024 以下端口。开发环境碰到这种情况要么用 root 启动要么换个高位端口。2.2 套接字四元组一条连接的身份证套接字Socket最直白的理解就是“IP 地址 端口号”的组合。IP 负责找主机端口负责找进程两者合在一起就是一个通信端点。而一条 TCP 连接是由四元组唯一定位的源 IP、源端口、目的 IP、目的端口。四元组完全相同的连接只能有一条任何一个元素不同就是另一条连接。这意味着“一台服务器最多只能有 65535 个连接”是个典型误区。服务器监听的是 80 端口但只要客户端来自不同 IP、不同源端口四元组就不同连接就可以无限多当然还会受文件描述符、内存等限制。很多人不理解服务端 accept 之后到底发生了什么accept 返回的是一个新的套接字文件描述符内核为这个新连接分配了新的四元组。监听套接字始终保持监听状态新连接和监听连接互不干扰。这也是为什么服务器可以同时保持百万级连接而监听端口永远只有那一个。2.3 客户端临时端口耗尽的现象与排查反过来看客户端侧确实有可能用完端口。每个出站 TCP 连接都要占用一个本地临时端口而临时端口范围默认是有限的。Linux 下可以查看cat /proc/sys/net/ipv4/ip_local_port_range很多发行版默认是 32768 到 60999 附近也就是约两万多个端口。短连接高并发场景比如一个进程每秒发起上千次 HTTP 请求且不复用连接很可能把临时端口耗尽报错通常是一句非常典型的Cannot assign requested address排查方法很简单看系统当前连接数量和端口分布ss -s ss -tan state time-wait如果发现大量 TIME_WAIT 连接占着临时端口不放那就不是“再加一个端口”能解决的问题了。优先做的是让客户端复用连接、缩小连接生命周期。改大 ip_local_port_range 只能带来短暂缓解不解决根本问题因为可用端口总有上限。3. UDP 与 TCP两套截然不同的传输哲学走到传输层最常见的灵魂拷问就是 UDP 和 TCP 怎么选。想搞清楚这个问题不是去背“TCP 可靠UDP 不可靠”这种结论而是要理解它们在设计取舍上走了完全不同的路。3.1 UDP 的无连接意味着什么UDP用户数据报协议先看特点没有握手过程不维护连接状态想发就发。首部只有 8 字节四个字段——源端口、目的端口、长度、校验和。发送时一次 write 对应一个报文段接收方 read 时按报文边界取数据这个特性叫“保留报文边界”。因为无连接、无状态UDP 的延迟极低CPU 开销也小还能支持广播和组播。TCP 是无法做广播的因为 TCP 是一条点对点连接而 UDP 可以把一份数据同时发给多个接收方。但代价也很直接丢包没人管乱序没人管重复没人管。网络发生拥塞时UDP 也不会主动减速它根本没有拥塞控制机制。我习惯把 UDP 比作“寄普通明信片”便宜、快、一次一张但丢了就丢了没人给你补发。TCP 则是“挂号信”要登记、要签收、丢了会补寄代价是流程长、开销大。3.2 TCP 的“重”和“稳”体现在哪里TCP传输控制协议和 UDP 几乎是两个物种。TCP 是面向连接的协议这个“连接”是一组内核数据结构包含序号、确认号、发送窗口、接收窗口、拥塞窗口、重传计时器……收发双方各维护一套。有了这些状态TCP 才能在这个不可靠的 IP 网络上提供可靠的字节流交付。可靠之外还有两个容易忽略的关键特性字节流TCP 不保留应用报文的边界。你 send 了两个 100 字节的数据对方可能一次 recv 到 200 字节也可能分成好几次。TCP 只保证字节顺序绝对按序不保证你的“消息”边界。这是很多新手写 TCP 通信程序时踩坑的地方——必须自己设计消息边界比如用长度前缀、分隔符或者固定结构。全双工一条 TCP 连接建立后数据可以同时在两个方向传输。这意味着关闭连接也比建立连接复杂因为两个方向都需要独立关闭后面讲四次挥手时会细说。3.3 选型不是二选一从 QUIC 看传输层演进把两者放在一起对比更清楚维度UDPTCP连接状态无连接面向连接可靠传输不保证确认、重传、排序数据组织报文边界保留字节流首部开销8 字节20 字节起流量控制无有拥塞控制无有广播/组播支持不支持代表性场景音视频、游戏、DNS、NTPHTTP、文件传输、邮件、数据库但实际选型千万别被这个表框死。UDP 上面完全可以做可靠传输——QUIC 就是最典型的例子它跑在 UDP 之上却实现了加密、可靠、有序、多路复用还自己实现了一套拥塞控制。这说明什么说明“可靠”不是 TCP 的专利而是传输机制的设计目标。如果你的实时通信场景需要低延迟但同时希望少丢数据完全可以参考 QUIC 的思路在 UDP 上自己设计序列号、确认和重传机制。我个人的选型习惯是需要严格一致性的业务数据走 TCP实时音视频、游戏同步这类容忍少量丢失的走 UDP弱网环境下的实时通信宁可花大力气在 UDP 上做 ARQ 和抖动缓冲也不要直接裸 TCP——TCP 的队头阻塞在弱网下会把延迟放大到无法接受。4. 可靠传输的底层拼图序号、确认、重传与滑动窗口TCP 的可靠传输看起来复杂拆开来其实就是四个词序号、确认、重传、滑动窗口。每一个都解决一个具体问题理解了问题机制自然就记住了。4.1 可靠传输的基础机制序号、确认、超时与快重传TCP 把要发送的应用数据看成一个连续的字节流每一个字节都会有一个序号。报文段头部里的“序号Seq”字段表示的是本报文段数据部分第一个字节的序号。确认机制是累计确认确认号ACK表示“对方期望我下一个发送的字节序号”。收到 ACK100意味着序号 99 及之前的字节全部收到了不用逐字节确认效率高很多。但光有确认不行丢了包要重传。怎么发现丢包靠两个机制超时重传发送方为每个包启动一个重传计时器RTO。RTO 不能设死要基于 RTT 动态估算业界一般用加权平均 RTT 再加上安全余量。如果超时还没收到 ACK就重传。快速重传发送方连收 3 个相同的重复 ACK大概率说明对方一直在等你缺的那段数据此时不等超时立即重传缺失的包。这是为了应对丢包但后续数据仍在流动的情况比傻等超时快得多。还有一个经常被忽略的扩展SACK选择性确认。它通过 TCP 选项告诉发送方“哪些乱序的数据我已经收到了”这样发送方就知道只需要补发真正丢失的那一小段而不是一把重传所有未确认数据。快速重传的判据是“3 个重复 ACK”但出现重复 ACK 不一定代表丢包。路径如果发生乱序先到的包也可能触发重复 ACK。所以不要把重复 ACK 直接等同于丢包还要结合前后报文段的时序判断。4.2 滑动窗口让传输从“一问一答”变成“流水线”如果没有窗口TCP 就是最原始的停等协议发一个包等一个 ACK再发下一个。这样信道利用率极低尤其在长距离高带宽链路上大部分时间都在等 ACK 的往返。滑动窗口解决的就是这个问题允许发送方在收到确认之前连续发送多个包。假设发送窗口是 4发送方可以连续发序号 1、2、3、4然后等 ACK。收到 ACK5说明 1 到 4 全部被确认窗口向前滑动允许发 5、6、7、8。数据像流水线上一样持续流动不用每发一个就停下来等确认。这里有一个和性能直接相关的概念带宽延迟积BDP 带宽 × RTT。要把一条链路跑满发送窗口至少要大于 BDP否则发出去的包还没飞到对方确认还没回来发送方已经被窗口卡住了。高带宽长链路下如果发现吞吐率上不去先看是不是窗口太小。4.3 流量控制与 Nagle别让网络被小包拖垮流量控制的本质是发送速率不能超过接收方的处理能力。TCP 首部里的“窗口”字段就是接收方通告的接收窗口rwnd我能接收多少字节就在 ACK 里告诉你。发送方的发送窗口取 min(通告窗口 rwnd拥塞窗口 cwnd)。如果接收方应用层不读数据缓冲区满了它就会通告一个零窗口发送方必须停下来直到收到新的窗口更新。“零窗口”会出现一个隐患如果接收方后来发送了“窗口非零”的更新包但这个包在路上丢了发送方会一直等接收方也在等数据双方死锁。TCP 为此设计了持续计时器当收到零窗口时发送方周期性发一个窗口探测包逼对方重新通告窗口。这个细节在实际网络故障里经常看到表现为连接活着但数据不动。还有一个经典问题叫糊涂窗口综合征发送方每次只发 1 字节接收方每次都通告小窗口。结果网络里全是首部 20 字节、数据 1 字节的小包效率极低。Nagle 算法就是为此设计的当上一个包还没被确认时先把小数据攒起来凑够一个 MSS 或者等到 ACK 再发。延迟确认一般等 40ms 或者攒两个包则让接收方尽量合并 ACK。但水能载舟亦能覆舟Nagle 算法和延迟确认遇到一起在交互式请求里可能造成额外 40ms 甚至更高的延迟。实时性敏感的应用通常要显式关闭 Nagle设置 TCP_NODELAY但代价是小包变多。5. 拥塞控制一条 TCP 流在网络堵车时的行为模式流量控制管的是“别把接收方撑爆”拥塞控制管的是“别把网络撑爆”。两者经常被弄混但问题域完全不同流量控制是点对点拥塞控制是整个网络所有流的资源分配问题。5.1 慢启动与拥塞避免先试探再加码TCP 的拥塞控制不是事前规划而是实时探测。它维护一个拥塞窗口cwnd表示发送方可发送的字节量。出发点很朴素不知道网络现在有多堵就先从小窗口开始没堵就加大堵了就减小。这个过程分成两个阶段慢启动阶段cwnd 从初始窗口开始每收到一个 ACKcwnd 加一个 MSS实际效果是每个 RTT 翻倍。假设初始窗口是 10第一个 RTT 后变成 20第二个变成 40……指数增长直到到达慢启动阈值 ssthresh。这个阶段名字叫“慢启动”其实一点都不慢指数增长很快真正的目的是“探测”。进入拥塞避免阶段后cwnd 每个 RTT 只增加 1 个 MSS线性增长而不是翻倍。因为此时已经接近网络容量再指数增长马上就会把网络打满。然后发生拥塞通常表现为丢包时怎么办这是 AIMD和式增加、积式减少的核心遇到超时说明网络已经严重拥塞ssthresh 减半cwnd 直接降回初始窗口遇到 3 个重复 ACK说明拥塞信号较弱进入快恢复而不是完全从头再来。5.2 快重传与快恢复丢了也能快速止损很多资料把快重传和快恢复分开讲实际上它们在 RFC 5681 之后是同一个流程。收到 3 个重复 ACK 时ssthresh 设置为当前 cwnd 的一半。cwnd 设置为 ssthresh 3MSS加 3 是考虑已经收到的 3 个重复 ACK 对应的数据已经从网络中移除了可以多放 3 个 MSS 进去。之后每收到一个重复 ACKcwnd 再增加 1 MSS相当于给“仍在途的乱序包”腾空间。直到收到新的 ACK说明丢失的包已经补齐cwnd 降到 ssthresh进入拥塞避免线性增长。为什么要这样设计因为 3 个重复 ACK 说明“后面的数据其实还在流动”网络的拥塞程度没有超时那么严重。直接回到慢启动重新指数探测是杀鸡用牛刀浪费时间不加控制地继续发又会加重拥塞。快恢复就是在这两者之间找一个平衡点。拥塞控制本质上不是“拥塞了才控制”它是一套持续运行的分布式资源分配协议。每一条 TCP 流都在不停地发送探测、观察信号、调整速率所有流共同竞争带宽。理解这一点再看 TCP 的窗口曲线就明白为什么它是锯齿形的了加一点、减一半再加一点、再减一半。5.3 CUBIC 与 BBR现代拥塞控制的两个方向经典 Reno 算法在高带宽长链路高 BDP下有个问题丢包后把 cwnd 砍半恢复速度取决于 RTT链路越长恢复越慢带宽利用率惨不忍睹。Linux 默认的 CUBIC 算法就是为了解决这个问题设计的。CUBIC 的思路是不再让窗口增长线性跟随 RTT而是用一个三次函数来控制窗口随时间的变化。丢包发生后先把窗口快速恢复到丢包前的水平然后再缓慢探测额外容量。这样即使 RTT 很大恢复也不会被拖得太慢所以在高速网络上表现远好于 Reno。BBR 是另一个思路。它完全不用丢包作为拥塞信号而是直接测量瓶颈带宽和最小 RTT估算出链路的带宽延迟积然后把发送速率稳定在那个值附近。这意味着 BBR 在“有一定丢包率但不严重”的链路上可以维持高吞吐而 CUBIC 往往因为少数丢包就把速率减半。我自己的实测体验是跨运营商、跨地区的高带宽链路丢包率稍高时 BBR 的吞吐经常比 CUBIC 稳很多。但它和 CUBIC 混跑时也会出现公平性问题所以生产环境切换拥塞控制算法之前最好先想清楚链路里是否有别的协议族的流量。6. 三次握手、四次挥手与 TIME_WAIT 的那些坑连接管理是面试必考也是线上故障的重灾区。这部分只要把“为什么是这个次数”想清楚再结合状态机排查问题基本就稳了。6.1 三次握手为什么是三次三次握手的过程大家都会背客户端发 SYN服务器回 SYNACK客户端再回 ACK。但为什么要三次为什么两次不行关键原因是客户端发出的第一个 SYN 有可能在网络中滞留很久然后在一个已经不存在的连接上重新出现。如果只有两次握手服务器收到这个迟到的 SYN 就会建立连接、分配资源但客户端早就放弃了这个连接不会给它发数据服务器的资源就白白浪费了。三次握手让服务器必须收到客户端的明确确认才能确认“客户端收到了我的 SYNACK、确实想要建立连接”。另一个作用是同步初始序号。双方各有一个初始序列号ISN三次握手时互相告知。序列号的作用是让双方知道数据传输从哪里开始也为后面的累计确认提供基准。线上偶发 SYN 队列满的情况表现为客户端一直 SYN_SENT服务器端 ss 能看到大量 SYN_RECV。常见原因有并发建连太高、半连接队列配置太小或者有异常流量在填满半连接队列。如果确认是正常业务优先调大队列长度而不是直接拒绝连接。6.2 四次挥手为什么比握手多一次TCP 是全双工的两个方向的数据流是独立的。关闭连接时每个方向都要单独关闭。第一次挥手主动方发 FIN表示“我的数据发完了你这边不会再收到我的新数据了”。对方回 ACK确认收到这个 FIN。 第二次挥手被动方如果还有数据要发可以继续发。数据发完后再发一个 FIN表示“我的数据也发完了可以关了”。主动方回 ACK。所以关闭需要四次两个方向各一次 FIN 各一次 ACK。握手的 SYN 和 ACK 可以合并成一次因为连接建立时服务器没有“先把自己数据发完再同意连接”的需求但关闭时被动方完全可能还有数据没发完不能强迫它立刻关。真正让运维头疼的是 TIME_WAIT。主动关闭的一方在发完最后一个 ACK 后不会立刻关闭而是进入 TIME_WAIT持续 2MSLMSL 是报文最大生存时间Linux 下 TIME_WAIT 通常约 60 秒。两个原因第一万一最后一个 ACK 丢了被动方会重发 FIN主动方需要能重新响应第二保证旧连接上的报文已经在网络中消失不会干扰到后续使用相同四元组的新连接。大量 TIME_WAIT 本身不是错误而是正常的协议行为。短连接服务端主动关闭连接时会有很多 TIME_WAIT如果数量大到影响新连接优先该做的是让客户端复用连接而不是粗暴地改内核参数。内核曾经的 tcp_tw_recycle 因时间戳问题造成过不少严重的兼容性故障一定不要在生产环境随便开启。6.3 连接故障现场SYN_SENT、SYN_RECV 与 RST排查连接问题先学会从ss的输出里读状态ss -tan状态分布能告诉你在连接的哪个阶段出了问题SYN_SENT 多客户端发了 SYN一直没收到 SYNACK。可能服务器没监听端口、防火墙丢包、半连接队列满。这时去服务器上看 SYN_RECV 的数量。SYN_RECV 多服务器收到了 SYN但完成不了握手。通常是半连接队列满了要么业务建连太快要么有人在制造大量半连接。RST 报文对方直接拒绝。端口没监听时的拒绝或者程序显式 abort 连接都会产生 RST。如果是访问一个未监听端口立刻收到 RST 是正常现象。大量 ESTABLISHED连接建好了但业务没进展要查应用层读写是否卡住以及 TCP keepalive 是否够灵敏。TCP keepalive 默认要等 2 小时才开始探测很多半开连接要挂很久才能被发现。做服务治理时我更推荐在应用层做心跳30 秒到 60 秒探测一次比 TCP keepalive 灵敏一个数量级。7. 用抓包把传输层机制调出来看一遍学了这么多协议细节最终还是要落在“能不能看到”。我一直建议所有做网络相关工作的同学至少完整地抓一次包亲眼看一下三次握手、ACK 确认、超时重传到底长什么样。7.1 抓包前的准备别被 checksum offload 骗了本地实验最简单的办法是起一个 HTTP 服务python3 -m http.server 8888然后用 tcpdump 在另一个终端抓包sudo tcpdump -i any -nn -S tcp port 8888打开 Wireshark过滤条件直接写tcp.port 8888第一次抓包的看到一片红、一堆 “TCP Checksum Incorrect” 别慌。现代网卡有硬件分载数据包从协议栈出来时校验和在网卡上才计算Wireshark 看到的是没来得及填校验和的包于是报错。这是抓包工具的正常现象不是线路故障。做本机回环测试时直接关闭校验和校验或者忽略这个提示就行。7.2 对着包看握手、确认与重传找一个 TCP 流右键选中过滤tcp.stream eq 0你就会看到完整的连接过程。第一个包是 SYN注意它的 Seq 值是相对序号显示为 0第二个包是 SYNACKSeq 是 0ACK 是 1——这里的 ACK1 表示“我期望你的第一个字节序号是 1”也就是已经收到了你的 Seq0 这个 SYN 包第三个包是 ACKSeq 是 1ACK 是 1。三次握手完成。接着发 HTTP 请求数据你会看到真正有意思的对应关系数据包的 Seq1表示“我的数据从序号 1 开始”服务器回复的 ACK 变成了新值表示“你这段数据我都收到了下一个期望从 XX 开始”。这就是序号和确认号最直观的体现——Seq 指向数据起点ACK 指向下一个期望字节。想观察重传可以用 tc 模拟丢包sudo tc qdisc add dev eth0 root netem loss 10%再抓包你会看到两种重传一种是隔了一段时间才出现的标着 “TCP Retransmission”这是超时重传另一种是短时间内连续出现重复 ACK然后触发快速重传的。超时重传的间隔能明显看到 RTO 的身影快速重传则几乎在重复 ACK 之后立刻发生。看完这一遍前面说的“为什么要有快速重传”就不用再背了你会直接理解等超时的代价。7.3 实际优化中的几个 TCP 参数抓包之外生产环境里最常调整的几个 TCP 参数我顺手列一下tcp_tw_reuse客户端开启后允许 TIME_WAIT 状态的连接复用本地端口发起新连接。依赖 tcp_timestamps 开启适合出站连接多的场景。SO_REUSEADDR服务端重启时经常报Address already in use打开这个选项可以快速复用处于 TIME_WAIT 的端口。不是性能调优是解决重启体验问题。TCP_NODELAY关闭 Nagle 算法降低小包延迟。交互式、实时性强的应用建议开启。BBR 拥塞控制高带宽长链路、有一定丢包率的场景可以切 BBRsysctl -w net.ipv4.tcp_congestion_controlbbr切之前确认内核对 BBR 的支持以及链路里是否存在大量 Reno/CUBIC 流避免公平性问题。最后说一句我自己的经验线上遇到“变慢”“卡顿”别先怀疑应用代码先抓包看传输层。把问题分成三类——是不是在重传是不是窗口打不开是不是在握手挥手上花了太多时间三类定位完绝大部分网络性能问题都能找到方向。传输层这层学扎实了往后的 HTTP/3、QUIC、内核网络调优学起来都会快很多。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑