
期末复习最怕的就是翻开课本发现全是字尤其是计算机网络这种概念密集的科目。第3章运输层是整个课程的分水岭前面两章讲的是“报文怎么在网络上走”从这一章开始才真正回答“两个程序之间怎么聊天”。如果你也在靠谢希仁《计算机网络》第八版备考或者准备408统考这一章的理解深度直接决定你最终能拿多少分。先说清楚这篇Part One覆盖的范围运输层的功能与端口概念、UDP协议、TCP报文段首部、可靠传输原理、流量控制。至于拥塞控制、连接管理和超时重传的复杂场景那是Part Two的内容咱们按阶段来别一口吃成胖子。今天我把这些基础知识按照“考试怎么考、实际协议怎么设计、到底为什么这么设计”三个维度拆开讲尽量把教材里那些绕口的表述翻译成人话同时保留你用来应付大题的专业术语和关键计算。1. 运输层到底在解决什么问题从“主机到主机”到“进程到进程”1.1 网络层和运输层的分工别再搞混了复习到这一章很多人第一个混乱点就是网络层已经有IP地址了为什么还需要端口号要回答这个问题得把两个层的职责画一条清晰的分界线。网络层IP协议的职责是把数据包从一台主机送到另一台主机它的寻址单位是IP地址。但这个送达只是“把信封放进楼栋信箱”并没有送到某个具体的人手里。一台主机上同时跑着浏览器、邮件客户端、在线游戏数据包到了主机之后操作系统怎么知道这段数据应该交给哪个程序这就是运输层要解决的——进程间的逻辑通信。教科书这里用了个很经典的说法IP协议提供的是主机之间的通信运输层提供的是进程之间的通信。考试如果出简答题问两者区别你把这个分界线写清楚再补一句“运输层对高层用户屏蔽了网络核心的细节包括路由选择、分组丢失、重复等问题”基本就是满分答案。1.2 复用与分用一对多的分发机制“复用”和“分用”这两个词看着抽象用快递站点理解就很好懂了。多个应用进程都要发数据就像很多包裹都塞进同一辆运输车这叫复用接收端收到包裹后按收件人端口分拣给不同应用这叫分用。复用分用的实现依赖两部分一是传输报文中的端口号字段让接收端能识别该交给哪个进程二是操作系统里的端口分配机制——发送端进程需要绑定一个本地端口接收端进程也要绑定自己的端口数据到达后内核通过端口的映射关系完成交付。这里有一个考试常出的小陷阱端口号只有16位取值0到65535。其中0到1023是知名端口Well-Known Port由IANA统一分配像HTTP的80、HTTPS的443、DNS的53、SSH的22都在这段区间。1024到49151是登记端口供用户进程或应用程序使用比如MySQL默认的3306就落在这个区间。49152到65535是短暂端口客户端程序临时使用每次连接时由操作系统随机分配。1.3 套接字TCP/IP网络编程的最小单元说到端口就绕不开套接字Socket。很多教材用“IP地址加端口号就是套接字”一句话带过但考试偶尔会考得更细一点套接字实际上是四元组由源IP、源端口、目的IP、目的端口共同确定。举个例子你本地IP是192.168.1.100浏览器用临时端口52000连百度的80端口套接字就是(192.168.1.100:52000, 某百度IP:80)。两台主机之间靠这个四元组唯一区分一条连接所以同一台机器上可以同时开很多个浏览器标签页只要每个连接用的临时端口不同即可。理解这一点对后面理解TCP连接管理特别重要——为什么三次握手要交换哪些信息、为什么TCP能区分多个并发连接根子都在套接字上。2. UDP短小精悍但不可靠为什么它依然活得很好2.1 UDP首部只有8个字节的极简设计UDP的全称是User Datagram Protocol用户数据报协议。它的首部固定8个字节源端口2字节、目的端口2字节、长度2字节、校验和2字节。和TCP动辄20字节起步的首部一比UDP确实算得上极简。这四个字段里长度指的是UDP用户数据报的总长度首部加数据最小值是8这个值表示数据部分为空。因为IPv4首部中已经包含协议类型和总长度所以实际上UDP长度字段即使出错也能从IP层推算出来但它保留了这个冗余设计。校验和则是对首部加数据一起计算如果校验失败UDP的处理策略非常简单粗暴——直接丢弃不通知源端。2.2 UDP校验和的计算伪首部的存在让很多人翻车UDP校验和的计算比TCP简单但有个独特的概念叫伪首部Pseudo Header。很多初学者第一次看到“12字节伪首部”时会困惑UDP首部不是只有8字节吗哪来的伪首部伪首部不是UDP报文的一部分它只是发送端和接收端在计算校验和时临时拼接的一个虚拟结构。它的内容是源IP地址4字节、目的IP地址4字节、01字节、协议字段值171字节、UDP长度2字节。总共12字节。为什么要拼进去IP层的字段因为UDP数据报在传输过程中如果IP层的源IP或目的IP错了UDP本身是无法感知的。在校验和里掺入IP地址相当于让UDP层也能对IP地址做一层校验。这种设计在TCP校验和里同样存在说明它是个通用的可靠性思路。计算过程三步把伪首部和UDP首部、数据拼接如果数据部分不是偶数个字节补一个全零字节只用于计算不发送按16位一组做二进制反码求和结果取反填入校验和字段。接收端把收到的校验和字段替换为全0重新计算一遍如果得到的结果是全1即反码求和结果为0说明数据没有差错。这里务必记住校验和中0有正负两种表示全0的发送结果表示校验失败发送端必须填充全1。这个细节408曾经出过多选题属于看着不起眼但真考了就血亏的点儿。2.3 UDP的工作特点与典型应用场景UDP的特点三个词总结无连接、不可靠、面向报文。无连接就是不需要握手直接发不可靠就是丢了数据不补发网络层把分组丢了就丢了UDP既不重传也不确认面向报文是指UDP把应用层交下来的数据原封不动地打包进报文不会像TCP那样按字节流切片重组。因为这些特性UDP主要用在三个场景实时性要求高、允许少量丢包的应用比如视频会议、网络电话、直播。偶尔卡顿可以接受但绝不能让声音画面等待重传那体验就全毁了。查询类短报文比如DNS查询、DHCP。这类请求一次交互就完事不需要建立连接UDP的轻量正合适。组播与广播比如IPTV、局域网发现服务。TCP是端到端协议根本无法支持一对多的发送UDP天然可以。考试如果问到“既然UDP不可靠为什么很多实时应用还用它”你要能答出这两点一是TCP重传造成的延迟无法满足实时性要求二是UDP没有拥塞控制不会因为网络拥塞而主动降低发送速度。3. TCP报文段首部每个字段背后的设计逻辑3.1 20字节固定首部面向连接可靠传输的基石TCP的首部比UDP复杂得多固定部分就20字节。如果把UDP首部比作一张名片TCP首部就是一份详细的合同书。逐字段过一遍源端口和目的端口各2字节和UDP一样用于复用分用。序号4字节本报文段数据部分第一个字节的序号。TCP是面向字节流的每个字节都有一个序号因为序号范围是2的32次方所以序号会循环使用。确认号4字节期望收到对方下一个字节的序号。注意是“期望”如果确认号是N说明序号N之前的数据都已正确收到。数据偏移4位表示TCP首部长度以4字节为单位。因为TCP可选字段长度可变所以需要这个值来指示数据从哪里开始。最小是5即20字节最大是15即60字节。保留位6位目前未用置0。控制位6位URG、ACK、PSH、RST、SYN、FIN每个控制位都是考试重点。窗口2字节允许对方发送的数据量单位是字节。这个值是接收端能做流量控制的直接依据最大65535字节。校验和2字节计算方法和UDP类似也要加伪首部只是协议字段值改成6。紧急指针2字节配合URG位使用指明紧急数据的末尾位置。3.2 六个控制位的真实含义不是背名字而是懂场景控制位是TCP协议状态转换的基础六个位各有各的用途考试经常给一个场景让你判断该设哪些位。URG紧急当URG置1时紧急指针有效。比如用户在Telnet会话里按CtrlC中断一个运行程序这个键盘中断信号就是紧急数据应该优先处理不能排在普通数据后面。ACK确认确认号有效。TCP规定连接建立后所有报文段都必须把ACK置1。所以三次握手里除了第一个SYN报文其余报文的ACK位都是1。PSH推送接收端应尽快将数据交给应用层不等待缓冲区填满。比如交互式应用敲完一行命令希望立即发送并尽快被响应。RST复位出现异常时释放连接或者拒绝一个不存在的连接。比如客户端向一个没有监听的端口发请求服务器会回一个RST。SYN同步连接建立时用于同步初始序号。SYN1、ACK0表示连接请求SYN1、ACK1表示同意建立连接。FIN终止发送方数据发送完毕请求释放连接。记住一个小技巧SYN和FIN只在连接的建立和释放阶段出现一旦连接建立SYN就再也不会出现而ACK是连接建立后每个报文都带的常客。3.3 序号与确认号TCP可靠性的第一层保障TCP的序号字段最容易理解错的地方在于序号不是按“报文段”编号而是按“字节”编号。课本上那句“TCP把数据看成一个无结构的字节流”不是空话它是理解整个可靠传输的钥匙。假设你发送1000字节的数据拆成两个报文段第一个500字节第二个500字节。如果第一个报文段的初始序号是1那么它数据部分的序号范围是1到500第二个报文段的序号是501到1000。确认号的逻辑是累积确认接收方收到序号501到1000的报文段后如果前面的1到500也收到了它回应的确认号就是1001表示“1000号之前的数据我全收到了请从1001开始发下一个”。累积确认的最大好处是即使中间有几个确认丢了接收方只要在收到下一个连续数据时确认一次发送方就能推断出前面的都收到了。这个累积确认机制既是TCP可靠传输的核心也是后面讲滑动窗口和重传策略的基础。考试计算题里经常给你序号和确认号让你推断哪些数据已确认、哪些还需要重传本质就是在考字节流序号的理解。4. 可靠传输的实现原理从停止等待到连续ARQ再到滑动窗口4.1 最简单的可靠传输停止等待协议要理解TCP为什么做得那么复杂最好的办法是先看那个最简单的模型——停止等待协议Stop-and-Wait ARQ。它的流程一句话发一个包等一个确认收到确认再发下一个。如果确认丢了怎么办停止等待协议用超时重传兜底——发送方启动一个计时器比如设定了2秒超过2秒还没收到确认就重发上一个数据包。这里必须区分两种丢失数据包丢了和确认包丢了。两种情况发送方看起来都是“没等到确认”所以它的应对措施一样超时后重传。停止等待协议的优点是无脑可靠缺点是效率极低。假设信道传播时延是10毫秒发送一个分组要1毫秒那一个来回要21毫秒这21毫秒里发送方有20毫秒在空等信道利用率大概只有5%。我用一个生活类比帮助记忆停止等待就像你叫外卖骑手送一单、你收到后打电话告诉他“收到了”、他再出发送下一单。如果等太久没回话你就打电话问“那单是不是丢了”如果确认丢了骑手也不敢确定你吃没吃到只能再送一份。4.2 流水线与连续ARQ协议用窗口换效率停止等待效率太低于是就有了流水线传输思路发送方不等确认连续发多个分组。计算机网络里真正的可靠传输协议包括TCP的底层模型都是基于这个思路也就是连续ARQ协议。连续ARQ分为两种后退N帧协议Go-Back-N和选择重传协议Selective Repeat。后退N帧的逻辑是发送窗口可以连续发多个分组而接收方只按序接收。如果某个分组丢了接收方丢弃失序到达的后续分组并重复发送对丢失分组的确认。发送方收到这个重复确认或超时后必须回退到丢失分组处把后面的分组全部重传。选择重传和改进思路则更精细接收方缓存失序到达的分组只要求发送方重传真正丢失的那个。代价是接收方要有足够的缓存空间发送方也要维护更复杂的窗口记录。TCP实际采用的是类似选择重传的机制配合SACKSelective Acknowledgment选择性确认选项可以精确通知发送方哪些字节到达了、哪些缺失了。这也是408统考比较侧重的知识点。4.3 TCP的滑动窗口机制发送窗口和接收窗口的协同TCP把连续ARQ落地为滑动窗口Sliding Window。发送方维护一个发送窗口窗口内的数据可以连续发送不需要等确认每收到一个累确认窗口就向前滑动。接收方维护一个接收窗口窗口外已经收到的数据交给应用层窗口内乱序到达的数据先缓存。这里有一个极其容易混淆的考点**TCP发送窗口的大小由什么决定**答案不是单一因素而是取两个窗口的最小值接收方通告的接收窗口rwnd即TCP首部的窗口字段和发送方根据拥塞程度估算的拥塞窗口cwnd。发送窗口 min(rwnd, cwnd)。前者管流量控制后者管拥塞控制两者机制不同、目的不同千万不能混为一谈。滑动窗口之所以能提高效率是因为它允许发送方在没有确认的情况下连续发送尽可能多的数据。窗口大小决定了网络管道里最多能有多少数据“在途”窗口越大流水线越满信道利用就越高。窗口大小也不是固定的TCP会在传输过程中动态调整这也是流量控制部分的核心内容。4.4 超时重传怎么计时不一样的往返时间TCP的超时时间RTORetransmission Timeout为什么难设设短了确认稍微晚一点就触发重传造成大量重复报文设长了一旦数据真丢了发送方要傻等很久才反应性能直线下降。TCP的RTO不是拍脑袋定的而是根据实时测量的**加权平均往返时间RTTRound-Trip Time**动态计算。每次发送报文段后记录发送时间收到确认后测得一个RTT样本再用指数加权移动平均的方式处理历史样本让新值平滑变化。标准的计算方法RFC 6298是SRTT (1 - α) × SRTT α × RTT RTTVAR (1 - β) × RTTVAR β × |SRTT - RTT| RTO SRTT max(G, 4 × RTTVAR)其中SRTT是平滑的RTT估计值RTTVAR是RTT的偏差G是系统时钟粒度α和β是经验系数常取1/8和1/4。计算的核心思路是超时时间不能只看平均值还要考虑波动幅度——网络越不稳定RTO就应该设置得越保守避免误判丢包。考试不太会让你套公式计算RTO但你要能解释清楚“为什么RTO不能设成固定的2秒”以及“RTT测量遇到重传报文段时怎么处理”——经典的教材问题是重传的确认到达后这个RTT样本到底算不算如果算可能会严重偏大或偏小。现代TCP的解决方案是使用**时间戳选项Timestamp**来精确测量每个报文的RTT不依赖模糊的去重判断。5. 流量控制滑动窗口怎么避免接收方被淹没5.1 为什么需要流量控制接收方不是无限吞吐的拥塞控制和流量控制经常被放到一起对比但它们是两个完全不同的问题。流量控制是端到端的接收方处理不过来让发送方“慢一点”。拥塞控制是整个网络层的某条链路拥堵了所有发送方要集体“退让”。流量控制的实现完全靠TCP首部的窗口字段rwnd。接收方在每次确认报文段时告诉发送方“我还有多少缓存空间”发送方据此调整发送窗口的上限。打个比方接收进程就像一只正在吃饭的碗发送方扔过来的数据是往碗里倒水。如果碗只有500毫升发送方每次最多只能倒400毫升留一点余量倒完等接收方说“我喝了一部分现在又有200毫升空间了”才能继续倒。这个“我还能装多少”就是rwnd。5.2 死锁问题与持续计时器一个必考的细节课本里最经典的流量控制案例是发送方收到rwnd0后停止发送但接收方随后发出的新公告rwnd200字节在网络上丢了。发送方继续傻等接收方也傻等——它以为发送方马上会发新数据实际上发送方在等它的新公告。双方就死锁了。TCP解决死锁的办法是持续计时器Persist Timer。发送方在收到rwnd0后启动一个计时器超时后主动发送一个窗口探测报文只有1字节数据。接收方即使窗口是0也必须回一个确认并在确认里带上当前的rwnd值。如果探测报文把新的rwnd带回去了死锁解除如果探测报文也丢了持续计时器会按指数退避重新发送直到收到回复。考试曾经这样出过题rwnd0后发送方为什么不能一直等下去答案就是持续计时器。复习时把这个例子和“死锁”这个关键词绑在一起记想丢分都难。5.3 rwnd为0但又要发送紧急数据怎么办有个更细的场景也值得注意接收方窗口为0发送方却有一条紧急数据要发。TCP的处理是URG位置1的紧急数据不受流量控制限制可以随时发送。这和前面控制位部分能对上——紧急数据的设计就是为了打破排队和限制优先到达接收端。这里顺便提醒一个通识点HTTP协议体量大的时候TCP流量控制造成的延迟会明显影响下载体验。很多面试问“为什么HTTP/2帧要分优先级、能做流控”底层基石就是TCP的这一套窗口机制。6. 期末考试容易丢分的位置我的复习建议6.1 三种协议报文的格式必须默写运输层大题第一个高频点是报文格式。UDP 8字节、TCP 20字节固定部分考试喜欢给你一个赋好值的报文段让你解析源端口、目的端口、序号、确认号、数据偏移、控制位然后判断它是什么类型比如是不是SYN报文。我的复习做法是先不看课本白纸上画一遍TCP首部每个字段标上字节数和含义然后和课本对照。第一遍画漏了哪个字段第二遍重点补哪个。重复三遍后基本能闭眼画出来。这个方法也适用于UDP首部和伪首部的结构虽然伪首部不算真首部但画出来有助于加深记忆。6.2 计算题的常见套路累计确认与窗口推进运输层的计算题主要集中在这几类给发送窗口大小和RTT算信道利用率给序号和确认号序列判断哪些报文段已确认、哪些应该重传给rwnd值和数据长度算还能发送的最大字节数。这类题目最关键的一步是把字节流序号图画出来用一条带刻度的直条表示数据流把每个报文段的序号范围标上去再把确认号推进的位置也标上。图一画对答案几乎就是顺着念出来的。很多同学丢分不是不会而是序号范围算错比如忘记了“确认号N表示N之前的所有字节都收到了”把边界弄错了。6.3 和面试八股的衔接这一章学得好后面事半功倍虽然这篇是期末复习向的内容但我还是要多说一句运输层不只是考试的分值所在它也是计算机网络面试八股的绝对核心。你如果以后要面大厂的后端、网络、基础架构岗面试官最爱问的TCP三次握手、四次挥手、重传机制、滑动窗口、拥塞控制全部来自这一章。所以我建议你现在复习的时候不要只背结论多问自己一层“为什么”。为什么确认号是累积的为什么接收窗口和拥塞窗口取最小值为什么超时时间要参考RTT方差这些问题想透了期末拿分只是一部分收获更长远的是为后续的TCP/IP协议栈理解打下扎实基础。这一篇Part One先到这里运输层的拥塞控制、连接管理三次握手与四次挥手、超时重传的细节以及TCP与UDP的完整对比放在Part Two继续写。你可以先把这一篇里的端口表、首部结构、滑动窗口这三个点练熟再往下推进。