ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

计算机网络自顶向下运输层详解:TCP与UDP协议、拥塞控制及实战调试

计算机网络自顶向下运输层详解:TCP与UDP协议、拥塞控制及实战调试 简介这份PPT课件面向计算机专业学生与网络初学者系统讲解计算机网络自顶向下方法中的运输层核心内容帮助读者从应用层需求出发理解端到端通信机制。课件围绕运输层服务、多路复用与分解、UDP无连接传输、TCP面向连接传输、可靠数据传输原理以及拥塞控制等模块展开涵盖rdt1至rdt3协议演进、回退N帧、选择重传、流量控制、连接管理与TCP吞吐量等关键知识点并配有家庭类比、套接字分解等直观示例适合课堂学习与期末复习使用。资源包共1个文件为ppt格式整体约1.82MB内容紧凑便于携带与演示。目前已有58人学习浏览可作为运输层章节的配套讲义帮助读者梳理协议层次关系、掌握TCP与UDP的差异及拥塞控制思路为后续网络编程与协议分析打下基础。1. 从一份“计算机网络自顶向下.ppt”说起运输层到底该怎么学才不翻车很多人第一次接触《计算机网络自顶向下方法》这门课都是被一份几十页的课件按在桌上摩擦。课件里从应用层一路往下讲到了运输层突然冒出 TCP 三次握手、四次挥手、流量控制、拥塞控制、UDP 协议栈、UDP 划分 IP 数据报片这一堆名词考试要考面试要问真到写代码调网络又发现完全对不上号。这份“计算机网络自顶向下.ppt”真正值钱的地方不是它把知识点罗列得多全而是它用自顶向下的顺序告诉你先看应用要什么再看运输层给什么最后才落到网络层怎么送。运输层是整门课的分水岭往上它要撑住 HTTP、DNS 这些应用往下它要压住 IP 层的不可靠。把 TCP 和 UDP 这两条路走通拥塞控制那几个窗口怎么变、iperf3 打流为什么丢包、read udp: unknown error到底卡在哪你心里才有底。这篇笔记就顺着这份课件的脉络把运输层从概念讲到能动手复现适合正在期末复习、准备 408、或者第一次写 socket 的从业者。2. 运输层的两条路TCP 与 UDP 到底怎么选2.1 先搞清楚运输层给应用承诺了什么自顶向下的讲法有个好处它逼你先回答“应用到底需要什么”。HTTP 要的是字节流按序到达少一个字节页面就乱DNS 要的是一次问答快速返回丢了大不了重发视频会议要的是延迟低宁可花屏也别卡三秒。运输层能提供的其实只有两件事多路复用/分用以及可选的可靠性。多路复用靠端口号把一台主机上不同进程的数据区分开这就是为什么tcp端口号和udp端口是两套独立空间同一个 53 端口 TCP 和 UDP 可以各占一份。TCP 在这之上加了连接、可靠、按序、流量控制、拥塞控制五件套UDP 几乎什么都没加只在 IP 之上贴了个端口和校验和。所以选型的第一原则不是“哪个快”而是“应用能不能接受丢包和乱序”。能接受就用 UDP不能接受才上 TCP。很多人一上来就说 UDP 快其实 UDP 快是因为它什么都不管代价是把重传、排序、拥塞这些活全甩给了应用层QUIC 就是这么被逼出来的。2.2 TCP 三次握手和四次挥手别只背状态机课件里 TCP 三次握手四次挥手是必考但光背 SYN、SYN-ACK、ACK 没用得知道每一步在解决什么。三次握手的本质是双方各自确认“我的发送能力”和“你的接收能力”都正常同时交换初始序列号 ISN。两次不够是因为服务端无法确认客户端收到了自己的 SYN-ACK四次多余因为中间两步可以合并。# 用 tcpdump 抓一次本机访问百度的握手过程 sudo tcpdump -i any -n tcp port 80 and host 110.242.68.66 -c 20 # 另开终端触发 curl -s -o /dev/null http://110.242.68.66抓包后你会看到Flags [S]、Flags [S.]、Flags [.]三个包方括号里的 S 是 SYN点是 ACK。序列号字段seq和确认号ack就是 ISN 的交换过程。挥手是四次因为 TCP 是全双工一方发 FIN 只表示“我没数据要发了”对方还可以继续发所以 ACK 和 FIN 通常分开。理解这一点看到curl: (35) tcp connection reset by peer就知道是对方在握手或传输中途直接发了 RST而不是正常挥手。2.3 UDP 协议栈与 IP 分片一次能发多大UDP 本身没有分段能力它把应用交下来的报文直接加上 8 字节头就丢给 IP。IP 层如果发现超过 MTU以太网通常 1500 字节就会做分片。这就是热词里说的udp划分ip数据报片。分片的风险在于任何一片丢了整个 UDP 报文都废而且接收端要等齐所有片才能重组延迟抖动很大。# Python 演示 UDP 发送超过 MTU 的报文观察 IP 分片 import socket s socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 1473 1500(MTU) - 20(IP头) - 8(UDP头)超过就会分片 payload bA * 4000 s.sendto(payload, (127.0.0.1, 9999)) print(sent, len(payload), bytes)这段代码发 4000 字节本机回环 MTU 通常 65536 不会分片但换成真实网卡就会看到多个 IP 分片。参数上安全做法是把应用层单包控制在 1472 字节以内1500 - 20 - 8或者干脆在应用层自己做分片和重组别依赖 IP 分片。iperf3使用udp打流时如果包长设成 1500 以上丢包率会明显上升就是这个原因。3. 拥塞控制与流量控制窗口到底怎么变3.1 流量控制和拥塞控制不是一回事这两个概念最容易混。流量控制是端到端的接收方通过 TCP 头里的窗口字段告诉发送方“我还能收多少”防止把接收缓冲区撑爆。拥塞控制是面向网络的发送方通过丢包和 RTT 猜测网络是不是堵了防止把链路压垮。前者看接收方后者看中间网络。课件里通常画两条曲线拥塞窗口 cwnd 和接收窗口 rwnd实际发送窗口取两者最小值。慢启动阶段 cwnd 从 1 个 MSS 开始指数增长到阈值后转拥塞避免线性增长遇到丢包根据版本不同处理。理解这个你才能解释为什么tcp流量控制和拥塞控制是面试高频——它直接决定了你的服务在弱网下表现如何。3.2 用 iperf3 观察拥塞窗口的实际影响光看公式没感觉动手打一次流最直观。iperf3 是常用工具服务端iperf3 -s客户端打 TCP 流。# 服务端 iperf3 -s # 客户端打 10 秒 TCP 流每秒报告一次 iperf3 -c 192.168.1.100 -t 10 -i 1 # 换成 UDP带宽 100M包长 1200 iperf3 -c 192.168.1.100 -u -b 100M -l 1200 -t 10TCP 模式下看Retr列重传次数多说明拥塞控制频繁触发UDP 模式下看Lost/Total和Jitter丢包高说明带宽打超了或者链路有问题。参数-l控制包长UDP 下建议 1200 左右给 IP 和 UDP 头留余量避免分片。-b是目标带宽设太高会人为制造丢包别拿这个结果去判断网络质量。3.3 从抓包看窗口的实际变化想更细就用 Wireshark 或 tcpdump 抓包看Win字段。接收方窗口变小说明应用读得慢发送方 cwnd 变小说明网络丢包了。# 抓包并只显示 TCP 窗口相关字段 sudo tcpdump -i eth0 -n tcp[tcpflags] tcp-ack ! 0 -c 50 -vv输出里的win就是接收窗口。如果它持续为 0就是零窗口发送方会停止发送并定期探测。这个现象在接收端应用处理慢时特别常见比如日志服务写磁盘卡住TCP 接收缓冲区满了窗口就归零。排查时先看应用层是不是阻塞再怀疑网络。4. 动手复现本地把 TCP 和 UDP 都跑一遍4.1 写一个最小 TCP 回显服务理论讲完必须落到代码。先写 TCP 服务端和客户端验证三次握手和字节流。# tcp_echo_server.py import socket server socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) server.bind((0.0.0.0, 9000)) server.listen(5) print(listening on 9000) while True: conn, addr server.accept() # 三次握手完成才返回 print(connected from, addr) while True: data conn.recv(1024) # 阻塞读字节流无边界 if not data: break # 对端关闭收到 FIN conn.sendall(data) # 回显 conn.close()SO_REUSEADDR让服务重启时不被 TIME_WAIT 卡住这是血泪经验。recv(1024)不保证一次收完一条消息TCP 是字节流应用层要自己定边界比如长度前缀或换行符。sendall会处理部分发送别用send然后假设全发出去了。4.2 写一个最小 UDP 回显服务UDP 没有连接代码更简单但边界要自己管。# udp_echo_server.py import socket server socket.socket(socket.AF_INET, socket.SOCK_DGRAM) server.bind((0.0.0.0, 9001)) print(udp listening on 9001) while True: data, addr server.recvfrom(2048) # 一次收一个数据报 print(from, addr, len, len(data)) server.sendto(data, addr) # 原样发回recvfrom一次返回一个完整数据报超过缓冲区会被截断所以缓冲区要开够。UDP 没有重传客户端如果没收到回显只能自己超时重发。udp网络调试时经常遇到read udp: unknown error (code10054)这是 Windows 上对方端口不可达时 ICMP 错误被映射上来的属于正常现象加个错误处理就行。4.3 用 nc 和 iperf3 做交叉验证代码跑通后用系统工具交叉验证确认不是自己代码的锅。# TCP 验证 nc -l 9000 # 或者用上面的 python 服务 echo hello tcp | nc 127.0.0.1 9000 # UDP 验证 nc -u -l 9001 echo hello udp | nc -u 127.0.0.1 9001nc是最轻量的调试工具能快速确认端口通不通。如果nc通而你的代码不通问题就在代码如果nc也不通先查防火墙和监听地址。0.0.0.0和127.0.0.1的区别经常导致“本机通、外部不通”这是新手最常见的翻车点。5. 避坑与排查运输层调试的五个常见问题5.1 现象服务端启动了但客户端连不上原因通常是监听地址绑成了127.0.0.1只接受本机连接或者防火墙没放行端口。解决bind用0.0.0.0然后ss -tlnp确认监听状态再检查iptables或firewalld。云主机还要看安全组。5.2 现象TCP 连接建立后马上被重置原因可能是服务端accept后没读数据就close或者客户端发的内容触发了服务端异常。解决抓包看 RST 是谁发的检查服务端日志。curl: (35) tcp connection reset by peer多半是服务端主动断的不是网络问题。5.3 现象UDP 发送成功但收不到回包原因可能是对方端口没监听ICMP 端口不可达被系统吞了或者包太大被分片后丢了。解决先用小包比如 100 字节测试确认链路通再逐步加大包长找到分片阈值。udp测试工具里输入 ASCII 命令没反应先确认目标端口和编码。5.4 现象iperf3 UDP 丢包率很高原因通常是-b设的带宽超过了实际链路容量或者包长超过 MTU 导致分片。解决把-b降到链路带宽的 80%-l设成 1200再看丢包。如果还高用ping -M do -s 1472确认路径 MTU。5.5 现象TIME_WAIT 太多导致端口耗尽原因是大并发短连接主动关闭方会进入 TIME_WAIT 持续 2MSL。解决开启tcp_tw_reuse或者改用长连接、连接池。别乱开tcp_tw_recycle它在 NAT 环境下会出玄学问题新内核已经移除。6. 进阶把拥塞控制参数调成适合自己业务的形状学完基础真正拉开差距的是知道哪些参数能调、调了会怎样。Linux 下sysctl能看到一堆 TCP 参数但别乱改先搞清楚每个的作用。参数默认值作用调整建议net.ipv4.tcp_congestion_controlcubic拥塞控制算法弱网可试 bbrnet.ipv4.tcp_rmem4096 131072 6291456接收缓冲区高带宽高延迟链路调大net.ipv4.tcp_wmem4096 16384 4194304发送缓冲区同上net.core.somaxconn4096accept 队列长度高并发调大net.ipv4.tcp_max_syn_backlog1024SYN 队列长度抗 SYN 洪泛调大查看当前算法sysctl net.ipv4.tcp_congestion_control。切 BBRsysctl -w net.ipv4.tcp_congestion_controlbbr需要内核支持。BBR 不靠丢包判断拥塞而是估带宽和 RTT在有一定丢包的链路上比 cubic 表现好但它对公平性有争议内网自用没问题公网服务要评估。验证方法很简单同一台机器同一目标分别用 cubic 和 bbr 跑iperf3 -c target -t 30对比吞吐和重传。注意要在业务低峰期做别影响线上。我一般会先在测试环境跑一周看ss -ti里的retrans和rtt变化再决定要不要上生产。缓冲区调优有个反直觉的点不是越大越好。缓冲区太大丢包前排队延迟会很高交互式应用体验反而差。所以tcp_rmem的上限要结合 BDP带宽延迟积算BDP 带宽 × RTT缓冲区至少等于 BDP 才能跑满带宽。比如 100Mbps、RTT 50msBDP 约 625KB默认 6MB 上限够用如果是 10Gbps、RTT 100msBDP 约 125MB就得调大。最后说个习惯每次改完参数用ss -ti看连接的cwnd、rtt、retrans用nstat看全局统计别凭感觉。网络这东西玄学多但数据不会骗人。希望帮到你。本文还有配套的精品资源点击获取
返回列表