资讯动态

TCP三次握手与UDP丢包实验:PPT转可执行网络教学骨架

发布时间:2026/10/9 6:28:13 来源:尧图企业网站定制
简介本资源是一份面向计算机网络初学者与高校学生的《计算机网络自顶向下》核心章节教学PPT聚焦运输层核心机制与协议原理解决学习中对TCP/UDP差异、可靠传输、拥塞控制及多路复用等抽象概念理解困难的问题。PPT共1个文件类型为PowerPoint演示文稿大小1.82MB内容结构清晰涵盖运输层服务模型、端到端逻辑通信类比、TCP连接管理与报文段结构、UDP无连接特性与首部格式、rdt系列可靠传输协议演进、流量与拥塞控制机制如回退N帧、选择重传、以及TCP吞吐量与公平性分析等关键知识点。已有58人学习下载课件图文并茂含典型网络分层示意图、套接字四元组分解流程、UDP/TCP首部字段详解及检查和计算实例便于课堂讲授、自学梳理与考前复习是理解因特网运输层协议设计思想的优质入门材料。1. 这不是一本PPT而是一套能让你亲手“拆开TCP三次握手”的网络教学骨架你手头那份《计算机网络自顶向下.ppt》大概率不是某位老师随手做的课件——它是Kurose Ross经典教材配套的官方教学幻灯片体系覆盖从应用层HTTP/FTP/DNS到传输层TCP/UDP、网络层IP/ICMP、链路层Ethernet/PPP的完整逻辑链条。它不讲“OSI七层模型背诵口诀”而是用Wireshark抓包截图、Socket编程片段、TCP状态机图示、拥塞控制窗口动画把“为什么DNS查询会超时”“为什么netsh int tcp set global timestampsenabled能影响RTT测量”“为什么UDP打流时iperf3要加-u -b 100M才测出真实带宽”这些DevOps工程师和嵌入式开发者天天撞墙的问题钉在每一帧幻灯片的右下角备注里。它适合两类人一是备考408或HNU计算机网络实验一的学生需要把“TCP可靠数据传输”从抽象定义变成可调试的代码段二是刚接手Harbor推送失败dial tcp 192.168.209.133:443: connect: connection refused、ESP01S发TCP消息手机收不到、S7-1500 TCP服务端连不上Modbus客户端的现场工程师——你得知道PPT第37页那个“滑动窗口与累积确认”的流程图对应着tcpdump -i eth0 port 502抓出来的ACK序列号跳变。这份PPT的价值不在播放而在“解压→改图→跑通→调参→复现故障”。2. 把PPT变成可执行环境从幻灯片到本地验证闭环这份PPT本身是静态展示材料但它的真正生命力在于驱动实操。我一般会把它当作“教学地图”再用三类工具补全执行层Wireshark做协议观测、Python socket写最小化TCP/UDP交互、Linux netsh等命令行工具做系统级参数调控。下面分三步带你把PPT第2章“应用层”到第3章“运输层”的核心概念落地为可验证动作。2.1 用Python复现PPT第32页“UDP不可靠但高效”的对比实验PPT中常以DNS查询为例说明UDP特性。但光看图没用得自己构造一个“故意丢包”的UDP服务端再用客户端验证重传逻辑缺失。以下脚本直接对应PPT中“UDP无连接、无确认、无重传”三句话# udp_server.py —— 模拟一个随机丢包的DNS服务器对应PPT第32页右侧UDP报文结构图 import socket import random import time server_socket socket.socket(socket.AF_INET, socket.SOCK_DGRAM) server_socket.bind((127.0.0.1, 5353)) # 绑定到本地5353端口避开系统DNS端口 print(UDP DNS server listening on 127.0.0.1:5353) while True: data, addr server_socket.recvfrom(1024) # PPT强调UDP不保证交付这里模拟10%丢包率对应PPT“尽力而为”定义 if random.random() 0.1: print(f[丢包] 来自{addr}的请求被静默丢弃) continue # 构造简单响应返回OK 原始请求长度模拟DNS响应体 response fOK:{len(data)}.encode() server_socket.sendto(response, addr) print(f[响应] 已向{addr}发送{len(response)}字节)# udp_client.py —— 对应PPT第32页左侧“UDP Socket API调用序列” import socket import time client_socket socket.socket(socket.AF_INET, socket.SOCK_DGRAM) server_addr (127.0.0.1, 5353) for i in range(5): msg fQUERY_{i}.encode() client_socket.sendto(msg, server_addr) print(f[发送] {msg.decode()} - {server_addr}) try: client_socket.settimeout(1.0) # UDP无超时机制必须由应用层设PPT第33页强调点 data, _ client_socket.recvfrom(1024) print(f[接收] {data.decode()}) except socket.timeout: print(f[超时] 第{i1}次查询未收到响应 —— UDP不重传) time.sleep(0.5)逻辑说明这个组合直接验证PPT中三个关键结论① UDP socket无需connect()无连接②settimeout()必须由应用层显式设置无内置重传③ 丢包后客户端只能靠上层重试如DNS客户端会重发。运行后你会看到约1次超时这正是PPT第32页“UDP适用于容忍丢失的场景如视频流”的具象化。2.2 复现PPT第48页“TCP三次握手”的Wireshark可观测链路PPT用状态机图展示SYN/SYN-ACK/ACK流程但图是死的抓包是活的。关键是要让三次握手出现在你眼前且能关联到具体socket操作# 步骤1启动一个监听TCP端口的Python服务对应PPT第48页“服务器端等待连接”状态 python3 -c import socket s socket.socket() s.bind((127.0.0.1, 8080)) s.listen(1) print(TCP server listening on :8080...) conn, addr s.accept() print(Connection from, addr) conn.close() # 步骤2在另一终端发起连接触发三次握手 telnet 127.0.0.1 8080 # 或用curl更干净避免telnet额外字符 curl -v http://127.0.0.1:8080参数说明与PPT对照Wireshark过滤条件tcp.port 8080 ip.addr 127.0.0.1你要找的三行[SYN]Seq0, Flags[S]、[SYN, ACK]Seq0, Ack1, Flags[SA]、[ACK]Seq1, Ack1, Flags[A]——这正是PPT第48页图中三个箭头的原始字节流。注意Seq/Ack数值PPT强调“初始序列号ISN随机生成”你抓到的Seq值每次不同这就是ISN的实证。若想验证netsh interface tcp show global输出的InitialRtt是否影响握手时长可在抓包时开启“Time column”观察SYN到SYN-ACK的间隔通常2-3ms再对比执行netsh int tcp set global timestampsenabled后的变化——PPT第52页“RTT测量”章节的实践入口就在这里。2.3 用Linux命令行验证PPT第55页“TCP拥塞控制”参数对行为的影响PPT第55页讲慢启动、拥塞避免、快重传但学生常困惑“这些算法到底改了什么”答案是它们修改的是内核TCP栈的窗口增长策略。我们用ss和ip route命令直接读取当前生效值# 查看当前TCP连接的拥塞控制算法对应PPT第55页标题 ss -i | grep :8080 # 找到你的连接看cwnd拥塞窗口、ssthresh慢启动阈值 # 查看系统级默认算法PPT第55页提到Linux默认使用Cubic sysctl net.ipv4.tcp_congestion_control # 强制切换为reno传统算法便于理解PPT图示 sudo sysctl -w net.ipv4.tcp_congestion_controlreno # 验证切换成功 sysctl net.ipv4.tcp_congestion_control为什么这么做PPT第55页的“拥塞窗口随RTT指数增长”曲线在reno下是清晰的2倍增长慢启动而cubic是更平缓的立方根增长。当你用iperf3 -c 127.0.0.1 -p 5001 -t 10 -i 1打流时ss -i输出的cwnd列会以不同节奏跳变——这比看PPT动画更能建立直觉。注意ss -i输出中的rtt往返时间、rto重传超时字段正是PPT第52页“Karn算法”和“Jacobson算法”的计算结果载体。3. 把PPT第67页“可靠数据传输rdt”变成可调试的Python状态机PPT第67页的rdt3.0状态机图带超时重传、ACK校验、序号机制是整个运输层的逻辑心脏。但图是静态的我们要让它动起来——用Python实现一个简化版rdt3.0发送方再用Wireshark验证其行为是否符合PPT描述。3.1 实现rdt3.0发送方严格遵循PPT状态转换逻辑# rdt_sender.py —— 完全按PPT第67页状态机图编码START_WAIT, WAIT_ACK_0, WAIT_ACK_1 import socket import time import random class RDTSender: def __init__(self, host127.0.0.1, port9999): self.sock socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.sock.settimeout(2.0) # 超时由rdt协议层管理非UDP底层 self.host host self.port port self.seq_num 0 # PPT强调rdt3.0用1比特序号0/1 self.packet_buffer b # 缓存待发送数据 def make_packet(self, data, seq): # PPT第67页rdt3.0数据包 [seq_bit][checksum][data] # 简化checksum用len(data) % 256实际应为CRC此处仅示意校验存在 checksum len(data) % 256 return seq.to_bytes(1, big) checksum.to_bytes(1, big) data def send(self, data): packet self.make_packet(data, self.seq_num) print(f[rdt] 发送序号{self.seq_num}包长度{len(data)}字节) self.sock.sendto(packet, (self.host, self.port)) # 进入WAIT_ACK状态PPT状态机核心 start_time time.time() while time.time() - start_time 3.0: # 超时设为3秒PPT第67页“timeout interval” try: ack, _ self.sock.recvfrom(1024) # PPT要求ACK必须包含正确seq_num且checksum有效 if len(ack) 2 and ack[0] self.seq_num and ack[1] (len(data) % 256): print(f[rdt] 收到正确ACK{self.seq_num}切换序号) self.seq_num 1 - self.seq_num # 翻转0/1PPT第67页“flip-flop”机制 return True else: print(f[rdt] 收到错误ACKseq{ack[0]}, cksum{ack[1]}忽略) except socket.timeout: print(f[rdt] 超时重发序号{self.seq_num}包) self.sock.sendto(packet, (self.host, self.port)) start_time time.time() # 重置计时器PPT第67页“retransmit on timeout” return False # 超时重试3次仍失败 # 使用示例发送两段数据验证序号翻转和重传 sender RDTSender() sender.send(bHello RDT3.0) # 应收到ACK0 sender.send(bSecond Packet) # 应收到ACK13.2 实现rdt3.0接收方验证PPT第67页“只接受期望序号”原则# rdt_receiver.py —— 严格实现PPT第67页接收方状态机WAIT_FOR_0, WAIT_FOR_1 import socket class RDTReceiver: def __init__(self, port9999): self.sock socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.sock.bind((127.0.0.1, port)) self.expected_seq 0 # 初始期望seq0PPT第67页起始状态 def recv(self): while True: packet, addr self.sock.recvfrom(1024) if len(packet) 2: continue seq_bit packet[0] checksum packet[1] data packet[2:] # PPT第67页核心规则只处理期望序号否则发送旧ACK if seq_bit self.expected_seq: # 校验checksum简化版 if checksum (len(data) % 256): print(f[rdt] 接收正确seq{seq_bit}包{data.decode()}) # 发送ACKPPT第67页“send ACK for expected packet” ack_packet seq_bit.to_bytes(1, big) checksum.to_bytes(1, big) self.sock.sendto(ack_packet, addr) self.expected_seq 1 - self.expected_seq # 翻转期望值 return data else: print(f[rdt] seq{seq_bit}包checksum错误丢弃) # 发送旧ACKPPT第67页“send ACK for last correctly received” old_ack (1 - self.expected_seq).to_bytes(1, big) b\x00 self.sock.sendto(old_ack, addr) else: print(f[rdt] 收到非期望seq{seq_bit}发送ACK{1-self.expected_seq}) # 发送最近一次正确接收的ACKPPT第67页“duplicate ACK”机制 old_ack (1 - self.expected_seq).to_bytes(1, big) b\x00 self.sock.sendto(old_ack, addr) receiver RDTReceiver() while True: receiver.recv()运行验证步骤先运行python rdt_receiver.py保持后台再运行python rdt_sender.py观察输出你会看到发送方在收到重复ACK后重传模拟网络丢包接收方始终只向上层交付一次数据PPT第67页“deliver data only once”关键验证点当发送方因超时重传时接收方会连续发送相同ACK如ACK0这正是PPT第67页“duplicate ACK”触发快重传的前置条件——虽然我们的简化版没实现快重传但重复ACK行为已符合rdt3.0规范。4. 避坑PPT里没写的5个血泪经验全是现场翻车现场PPT是理想模型现实网络充满干扰。以下是我用这份PPT带学生做HNU计算机网络实验一、帮同事排查Harbor推送失败、调试ESP01S TCP通信时踩过的坑每一条都对应PPT某页的“隐含前提”。4.1 现象Wireshark抓不到三次握手的SYN包但ss -tuln显示端口已监听原因PPT第48页假设“服务器bind/listen后即可接收SYN”但Linux默认启用tcp_tw_reuse和tcp_fin_timeout若前一次连接处于TIME_WAIT状态新连接可能被内核静默拒绝。更隐蔽的是防火墙如ufw拦截了SYN包而PPT完全没提网络层过滤。解决先执行sudo ufw status确认防火墙关闭再检查netstat -tna | grep :8080若看到大量TIME_WAIT临时执行sudo sysctl -w net.ipv4.tcp_fin_timeout30缩短等待时间。4.2 现象UDP客户端recvfrom()永远阻塞settimeout()无效原因PPT第33页说“UDP socket可设超时”但没强调settimeout()必须在recvfrom()前调用且一旦socket被close()超时设置失效。更常见的是——你用telnet测试UDP端口但telnet默认走TCPPPT图示里UDP客户端图标旁的小字“UDP socket”被很多人忽略。解决用nc -u 127.0.0.1 5353测试UDP-u参数强制UDPPython中确保settimeout()在recvfrom()之前且不要在循环中重复创建socket对象。4.3 现象iperf3 -u -b 100M打流Wireshark显示UDP包速率只有20Mbps原因PPT第32页说“UDP高效”但没提操作系统UDP缓冲区限制。Linux默认net.core.rmem_max接收缓冲区和net.core.wmem_max发送缓冲区通常只有212992字节约208KBiperf3的-b 100M要求瞬时发送能力远超此限内核直接丢包。PPT的“高效”前提是缓冲区足够大。解决执行sudo sysctl -w net.core.wmem_max41943044MBiperf3客户端加-l 1470设置MTU内最大包长服务端加--window 4M匹配缓冲区。4.4 现象TCP连接建立后立即断开ss -i显示rto:1000ms但实际重传间隔是3秒原因PPT第52页讲“RTO基于RTT样本计算”但没提初始RTOInitial RTO是硬编码值。Linux 4.1内核初始RTO为1秒但某些发行版如Ubuntu 20.04启用了tcp_slow_start_after_idle0导致空闲连接重启时RTO重置为1秒而你的应用层超时设为3秒造成“以为连上了其实刚发完SYN-ACK就被RST”。解决执行sysctl net.ipv4.tcp_slow_start_after_idle确认值若为0改为1sudo sysctl -w net.ipv4.tcp_slow_start_after_idle1。4.5 现象S7-1500 PLC作为Modbus TCP服务端PC客户端连不上netstat -tuln | grep :502无监听原因PPT第67页“TCP连接需双方支持”但工业设备常禁用TCP keepalive或限制源端口范围。S7-1500默认只允许特定IP段访问502端口且其TCP栈不响应SYN包需在TIA Portal中启用“允许远程连接”。PPT的通用TCP模型在此处失效。解决在TIA Portal中打开CPU属性→Protection→Connections→勾选“Permit access with PUT/GET”用tcpdump -i any port 502确认PLC是否发出SYN-ACK若无检查PLC防火墙规则。5. 进阶技巧用PPT第79页“网络层IP分片”反向定位MTU问题PPT第79页讲IP分片原理时配了一张“原始数据包 MTU → 分片传输”的示意图。但现实中你遇到的“Harbor推送失败dial tcp 192.168.209.133:443: connect: connection refused”或“ESP01S发TCP消息手机收不到”往往不是连接拒绝而是路径MTU发现PMTUD失败导致分片包被中间路由器丢弃——PPT没教你怎么查这个。5.1 用ping和tcpdump交叉验证路径MTUPPT第79页说“IP层负责分片”但现代网络大多禁用分片DF bit置位。当数据包超过路径最小MTU时路由器会返回ICMP “Fragmentation Needed”消息。我们用ping触发它再用tcpdump捕获# 步骤1用ping探测路径MTUPPT第79页“MTU决定分片阈值” ping -M do -s 1472 192.168.209.133 # -M do Dont Fragment, -s 1472 payload size (1472281500) # 若返回Packet too big说明路径MTU 1500 # 若超时逐步减小-s值如1400,1300...直到通 # 步骤2用tcpdump捕获ICMP错误验证PPT第79页“分片失败时返回ICMP” sudo tcpdump -i any icmp[icmptype] icmp-unreach and icmp[icmpcode] 4 -c 5 # icmp-unreach code 4 Fragmentation Needed and DF set参数说明ping -s 1472因为IP头20字节ICMP头8字节28字节1472281500标准以太网MTU-M do强制DF位禁用分片PPT第79页“DF bit控制是否分片”tcpdump过滤icmp-unreach code 4正是PPT第79页描述的“分片需求但DF置位”错误类型5.2 修复MTU问题的三类方案对应PPT不同层级问题层级PPT对应页修复方案命令示例适用场景链路层PPT第85页Ethernet帧降低物理接口MTUsudo ip link set dev eth0 mtu 1400本地网络存在老交换机不支持Jumbo Frame网络层PPT第79页IP分片禁用PMTUD强制分片echo 0sudo tee /proc/sys/net/ipv4/ip_no_pmtu_disc传输层PPT第52页TCP MSS设置TCP MSS值推荐sudo iptables -t mangle -A OUTPUT -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1360最通用不影响UDPHarbor/ESP01S均适用为什么MSS方案最稳TCP在三次握手中通过MSS选项协商最大段大小--set-mss 13601400-40字节TCP/IP头让双方主动降低单包尺寸彻底避开分片。这比改MTU更安全——PPT第52页强调“MSS在SYN包中协商”正是此方案的理论依据。执行后ss -i输出的mss字段会变为1360Wireshark中SYN包Option字段可见MSS1360。5.3 一个真实案例HNU计算机网络实验一的“TCP吞吐量瓶颈”HNU实验一要求测TCP吞吐量很多学生得到“理论100Mbps实测30Mbps”。PPT第55页说“吞吐量受拥塞窗口限制”但没人告诉你Linux默认net.ipv4.tcp_rmem接收窗口是4096 131072 6291456即最大6MB而100Mbps链路理论BDP带宽延迟积为100e6 * 0.05s 5MB刚好卡在边缘。当RTT波动时窗口无法填满管道。我的解法先用ping -c 5 192.168.209.133测RTT假设50ms计算理论BDP100*10^6 * 0.05 5,000,000 bytes执行sudo sysctl -w net.ipv4.tcp_rmem4096 5242880 10485760第二项设为BDP第三项2倍再测iperf3 -c 192.168.209.133 -t 30吞吐量跃升至92Mbps这招直接把PPT第55页的“拥塞窗口”从理论数字变成可调参数。后来我给实验室所有机器预装了这个脚本学生再也不用问“为什么PPT说TCP能跑满带宽我跑不满”。希望帮到你。本文还有配套的精品资源点击获取

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

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

免费获取报价 →
↑