拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

计算机网络实验报告写作指南:从抓包到协议分析的全流程解析

计算机网络实验报告写作指南:从抓包到协议分析的全流程解析

简介:本资源是一份面向计算机网络课程学习者与实验实践者的TCP协议深度解析型实验报告,聚焦传输层核心机制的理解与实现。报告完整覆盖RDT 2.0至3.0的迭代演进、选择响应协议设计,以及Reno算法下的慢开始、拥塞避免、快重传与快恢复等关键拥塞控制策略,通过LOG文件分析与状态日志增强(如每轮次输出cwnd/ssthresh)解决教学中难以直观观察动态过程的痛点。资源为单个Word文档(.doc),共1个文件,大小945KB,结构清晰,含学号姓名等标准报告格式及5大模块详细分析、困难总结、迭代开发反思与教学建议。内容预览显示其严格对应实验评分要点,包含代码与日志联动分析、未完成项归因及可落地的改进方案。目前已有291人学习下载,适合高校本科生开展网络协议仿真实验、撰写课程报告或深入理解TCP底层行为逻辑。

1. 为什么一份《计算机网络实验报告.doc》比你想象中更难写对:从抓包失败到协议分析翻车的完整闭环

你刚在Wireshark里抓了一堆TCP三次握手的包,截图贴进Word,配了句“可见客户端发送SYN,服务端回SYN-ACK”,就准备交作业?别急——这份《计算机网络实验报告.doc》不是PPT截图汇编,而是你对OSI七层模型、以太网帧结构、IP分片机制、TCP状态机、HTTP语义甚至NAT穿透逻辑的一次可验证、可复现、可被质疑的工程实录。我带过三届网络实验课,90%的学生卡在“能跑通但说不清为什么”,比如ping通了却解释不了ICMP Type Code字段含义,Telnet连上了却画不出应用层到物理层的完整数据封装路径。这份报告真正的价值,不在于格式多规范,而在于它能否经得起老师一句追问:“你抓到的这个FIN包,它的Sequence Number和Acknowledgment Number为什么是这个值?请结合RFC 793图6的状态迁移图说明。”——本篇就带你用真实命令、真实抓包、真实配置,把这份看似简单的.doc文件,写成一份有数据支撑、有协议依据、有排错痕迹的技术文档。适合正在赶实验 deadline 的本科生、需要复现实验细节的助教,以及想用真实网络行为反向验证理论模型的自学者。


2. 实验环境搭建:用VirtualBox+Ubuntu+Wireshark构建可复现的最小网络拓扑

做网络实验最怕“在我机器上好好的”,所以第一步必须固化环境。我们不用云主机或学校机房那种黑匣子,而是用VirtualBox本地搭一个三节点拓扑:一台Ubuntu Server作路由器(启用IP转发),两台Ubuntu Desktop作Client A和Client B,全部桥接至物理网卡,确保能访问外网且彼此隔离。这样所有抓包、路由表、iptables规则都可控、可截图、可复现。

2.1 创建三台虚拟机并配置网络模式

提示:务必全部使用桥接模式(Bridged Adapter),不要用NAT或Host-only。NAT会隐藏真实IP,Host-only无法访问外网,都会导致后续HTTP抓包、DNS解析等环节失真。

# 在每台Ubuntu虚拟机中执行(以Client A为例) sudo ip addr add 192.168.10.10/24 dev eth0 sudo ip link set eth0 up sudo ip route add default via 192.168.10.1 # 指向路由器

路由器节点额外执行:

# 启用IPv4转发 echo 'net.ipv4.ip_forward=1' | sudo tee -a /etc/sysctl.conf sudo sysctl -p # 配置iptables SNAT(让Client A/B能访问外网) sudo iptables -t nat -A POSTROUTING -s 192.168.10.0/24 -o eth1 -j MASQUERADE sudo iptables -t nat -A POSTROUTING -s 192.168.20.0/24 -o eth1 -j MASQUERADE

2.2 验证连通性与路由表

关键不是“ping通”,而是确认路径经过预期设备。在Client A上执行:

# 追踪到百度的路径(应经过路由器192.168.10.1) mtr -r -c 5 www.baidu.com # 查看本机路由表(确认default via指向路由器) ip route show # 在路由器上抓包验证转发(在eth0口抓Client A发包,在eth1口抓转发后包) sudo tcpdump -i eth0 host 192.168.10.10 -w router_eth0.pcap & sudo tcpdump -i eth1 host 192.168.10.10 -w router_eth1.pcap &

参数说明:

  • mtr -r -c 5生成5次探测的统计报告,比单纯ping更能暴露中间跳点丢包;
  • tcpdump -i eth0 host 192.168.10.10精确过滤Client A流量,避免混入其他设备噪声;
  • -w router_eth0.pcap直接保存为pcap文件,后续可导入Wireshark逐帧分析,这是报告里“证据链”的源头。

2.3 Wireshark基础配置:过滤器与时间戳精度

很多学生报告里截图模糊、时间戳乱跳,根源在Wireshark设置。打开Wireshark → Edit → Preferences → Protocols → IEEE 802.11,勾选“Enable decryption”(即使不用WiFi,此选项影响底层时间戳精度);在Capture Options中,取消勾选“Update list of packets in real time”,避免高负载时丢包;最关键的是设置显示过滤器模板:

过滤器名称过滤表达式用途
TCP三次握手tcp.flags.syn == 1 and tcp.flags.ack == 0 or tcp.flags.syn == 1 and tcp.flags.ack == 1快速定位SYN/SYN-ACK/FIN包
HTTP请求头http.request.method == "GET" && http.host contains "baidu"精准提取目标网站HTTP流
ICMP错误icmp.type == 3 or icmp.type == 11抓取Destination Unreachable或TTL Exceeded

注意:Wireshark的显示过滤器(Display Filter)和捕获过滤器(Capture Filter)完全不同。前者在抓包后筛选,后者在抓包时丢弃无关包。实验报告中所有截图必须标注使用的是哪种过滤器,否则结论不可信。


3. 核心实验操作:从ICMP到HTTP的四层协议抓包与字段级分析

实验报告的灵魂不在截图数量,而在每一帧数据包的字段解读是否精准对应RFC标准。我们按协议栈自下而上实操:先抓ICMP验证网络层可达性,再抓TCP三次握手看传输层连接建立,最后抓HTTP GET请求分析应用层语义。所有操作均在Client A上完成,所有抓包文件保存为exp1_icmp.pcap、exp2_tcp.pcap、exp3_http.pcap,便于报告中交叉引用。

3.1 ICMP抓包:不只是ping,要解析Type/Code/Checksum

执行ping -c 3 192.168.10.1(ping路由器),同时Wireshark抓包。关键不是看到Reply,而是定位到ICMPv4帧(EtherType=0x0800, IP Protocol=1),然后展开ICMP头部:

Internet Control Message Protocol Type: 8 (Echo (ping) request) ← 注意:不是"Request",RFC 792写的是"Echo Request" Code: 0 Checksum: 0x23a1 [unverified] ← 此处需手动验证:用Wireshark右键→"Validate checksum" Identifier: 0x0001 (1) Sequence number: 1 Data: 000000000000000000000000000000000000000000000000...

字段验证方法:

  • 右键该ICMP包 → Protocol Preferences → ICMP → 勾选“Validate checksum”,Wireshark会标红错误校验和;
  • Sequence number必须与ping命令输出的“seq=1”严格一致,这是判断是否同一请求的关键;
  • Data字段前8字节是Unix时间戳(微秒级),可用date -d @$(printf "%d" 0x$(xxd -p -l8 exp1_icmp.pcap | cut -c1-16))反向计算发送时间。

3.2 TCP三次握手:用tshark命令行提取关键字段

GUI截图易失真,我们用tshark导出CSV供报告表格引用:

# 导出三次握手的Seq/Ack/Flags字段(仅首包) tshark -r exp2_tcp.pcap -Y "tcp.flags.syn==1 and tcp.flags.ack==0" \ -T fields -e frame.number -e ip.src -e ip.dst -e tcp.srcport -e tcp.dstport \ -e tcp.seq -e tcp.ack -e tcp.flags.syn -e tcp.flags.ack -E header=y -E separator=, > syn.csv # 输出示例: # frame.number,ip.src,ip.dst,tcp.srcport,tcp.dstport,tcp.seq,tcp.ack,tcp.flags.syn,tcp.flags.ack # 1,192.168.10.10,192.168.10.1,54321,80,0,0,1,0 # 2,192.168.10.1,192.168.10.10,80,54321,1000,1,1,1 # 3,192.168.10.10,192.168.10.1,54321,80,1,1001,0,1

参数说明:

  • -Y "tcp.flags.syn==1 and tcp.flags.ack==0"是显示过滤器,精确匹配SYN包;
  • -T fields指定输出字段模式,比GUI复制更可靠;
  • -E header=y -E separator=,生成带表头的CSV,可直接粘贴进Word表格;
  • 关键验证点:第二包的tcp.ack必须等于第一包的tcp.seq + 1(即0+1=1),第三包的tcp.ack必须等于第二包的tcp.seq + 1(即1000+1=1001),这是TCP可靠传输的基石。

3.3 HTTP抓包:分离TCP流并提取URI与User-Agent

执行curl -v http://httpbin.org/get?test=1,抓包后用Wireshark的Follow → TCP Stream功能分离HTTP流。重点不是看到GET请求,而是验证HTTP/1.1协议字段:

GET /get?test=1 HTTP/1.1 Host: httpbin.org User-Agent: curl/7.68.0 Accept: */*

必须在报告中体现的三个细节:

  1. Host字段存在性:HTTP/1.1强制要求Host头,若缺失则服务器返回400 Bad Request;
  2. User-Agent真实性:对比curl --version输出,确认字符串完全一致(含空格和斜杠);
  3. 响应状态行解析:HTTP/1.1 200 OK中的200是Status Code,OK是Reason Phrase,二者在RFC 7230中定义不同作用。

血泪经验:很多学生把Wireshark自动重组的HTTP流当原始数据,但实际网络中HTTP是跨多个TCP段传输的。正确做法是右键HTTP流 → "Export Object → HTTP",保存原始HTTP payload,再用hexdump -C exported_http查看十六进制,确认\r\n分隔符真实存在。


4. 报告撰写避坑:从格式陷阱到协议误读的5个致命问题

写报告最怕“看起来很专业,一问就露馅”。以下是我在批改327份《计算机网络实验报告.doc》中总结的高频翻车点,每一条都对应真实扣分案例。

4.1 现象:截图中Wireshark时间戳显示“0.000000”,但文字描述“延迟约23ms”

原因:未开启Wireshark的“Relative time”显示模式,所有时间戳都是绝对时间(从抓包开始计时),而0.000000只是第一帧。学生误将绝对时间差当作RTT。
解决:View → Time Display Format → “Seconds Since Beginning of Capture”,再右键列标题→“Column Preferences”→添加“Delta Time”列,该列才真实反映两帧间隔。

4.2 现象:TCP状态机图标注“CLOSED→SYN_SENT”,但RFC 793图6明确写的是“CLOSED→SYN-SENT”(连字符非下划线)

原因:直接复制网络图片或教材扫描件,未核对RFC原文。RFC中所有状态名均为大写+连字符(如SYN-SENT、ESTABLISHED)。
解决:在报告中所有协议状态名,必须与RFC 793 Section 3.2 Table 2完全一致,包括大小写和符号。可直接从RFC PDF复制,避免手打错误。

4.3 现象:声称“抓到DNS查询返回A记录”,但Wireshark中DNS响应Flags显示“0x8180”(标准响应),而学生标注为“0x8000”(仅QR位)

原因:只看了Flags字段的十六进制值,未展开解析各比特位。0x8180 = 1000000110000000,其中第15位QR=1(Response),第11位RA=1(Recursion Available),学生漏看RA位。
解决:在Wireshark中右键Flags字段→“Expand Subtree”,逐位确认QR、AA、TC、RD、RA、Z、AD、CD各标志位,报告中需注明“RA=1表明递归查询被支持”。

4.4 现象:HTTP请求截图显示“Connection: keep-alive”,但结论写“本次请求后TCP连接立即关闭”

原因:混淆HTTP Connection头与TCP FIN包。Keep-Alive是应用层提示,TCP连接是否关闭取决于是否有FIN包。
解决:在抓包中搜索tcp.flags.fin == 1,确认FIN包出现时机。若HTTP响应后无FIN,则连接保持;若有FIN,则连接关闭。报告中必须写明“观察到FIN包在Frame X发出,故TCP连接于此时终止”。

4.5 现象:IP分片实验中,报告称“第二片偏移量为1480”,但Wireshark显示“Fragment offset: 1480”

原因:IP分片偏移量单位是8字节,1480×8=11840字节,而MTU通常为1500,显然矛盾。真实偏移量应为1480÷8=185(十进制)。
解决:Wireshark默认显示的是换算后的十进制偏移量(即185),但字段名仍叫“Fragment offset”。报告中必须注明“偏移量185表示该片数据起始于原始IP数据报的第1480字节(185×8)”,避免单位混淆。


5. 进阶技巧:用Python自动化提取关键指标,让报告数据可验证、可复现

手工数包、抄字段、算校验和,效率低且易错。我用Python写了一个report_helper.py,输入pcap文件路径,自动输出实验报告所需的核心表格和验证结论。它不替代你的思考,而是把重复劳动交给代码,让你专注协议逻辑本身。

5.1 自动化提取TCP三次握手时序与窗口值

# report_helper.py from scapy.all import rdpcap, TCP, IP import pandas as pd def analyze_handshake(pcap_path): packets = rdpcap(pcap_path) handshake = [] for pkt in packets: if TCP in pkt and IP in pkt: tcp = pkt[TCP] ip = pkt[IP] if tcp.flags & 0x02: # SYN flag handshake.append({ 'frame': len(handshake)+1, 'src_ip': ip.src, 'dst_ip': ip.dst, 'src_port': tcp.sport, 'dst_port': tcp.dport, 'seq': tcp.seq, 'ack': tcp.ack, 'win': tcp.window, 'flags': format(tcp.flags, '06b') # 二进制显示flags }) return pd.DataFrame(handshake) # 调用示例 df = analyze_handshake("exp2_tcp.pcap") print(df.to_string(index=False))

输出效果:

frame src_ip dst_ip src_port dst_port seq ack win flags 1 192.168.10.10 192.168.10.1 54321 80 0 0 64512 000010 2 192.168.10.1 192.168.10.10 80 54321 1000 1 64512 010010 3 192.168.10.10 192.168.10.1 54321 80 1 1001 64512 000010

关键设计:

  • format(tcp.flags, '06b')将TCP flags转为6位二进制(URG, ACK, PSH, RST, SYN, FIN),比Wireshark的十六进制更直观;
  • win字段直接提取tcp.window,避免手动查Wireshark窗口大小缩放因子(Window Scale Option);
  • 所有数值均为原始抓包值,不经过任何Wireshark解码干预,保证可复现。

5.2 自动验证ICMP校验和并生成报告段落

def verify_icmp_checksum(pcap_path): packets = rdpcap(pcap_path) for pkt in packets: if pkt.haslayer(ICMP): icmp = pkt[ICMP] # Scapy自动重算校验和 recalculated = icmp.__class__(bytes(icmp)).chksum if icmp.chksum != recalculated: return f"❌ ICMP校验和错误:抓包值{icmp.chksum} ≠ 重算值{recalculated}" return "✅ 所有ICMP包校验和验证通过" # 调用 print(verify_icmp_checksum("exp1_icmp.pcap"))

为什么这比Wireshark GUI更可靠:
Scapy的__class__(bytes(icmp))会完全重建ICMP包,包括填充字节(padding)、校验和字段清零等RFC 792要求的步骤,而Wireshark的“Validate checksum”可能受显示设置影响。这个函数结果可直接粘贴进报告“校验和验证”章节。

5.3 生成可直接插入Word的Markdown表格

报告里大量需要对比不同协议字段,手动对齐痛苦。report_helper.py内置generate_protocol_table()函数:

def generate_protocol_table(): data = [ ["协议", "字段名", "长度(字节)", "取值示例", "RFC依据"], ["IP", "Total Length", "2", "0x05dc (1500)", "RFC 791 Sec 3.1"], ["TCP", "Window Size", "2", "0xfa00 (64000)", "RFC 793 Sec 3.1"], ["HTTP", "Status Code", "3", "200", "RFC 7231 Sec 6"] ] return "\n".join(["| " + " | ".join(row) + " |" for row in data]) # 输出即为标准Markdown表格,复制进Typora或Word(支持Markdown粘贴)即可

我的习惯:每次实验后运行python report_helper.py exp2_tcp.pcap > results/exp2_summary.txt,把输出内容拖进Word,再人工补充分析。这样既保证数据源头干净,又保留你的技术判断——毕竟,自动化是工具,不是替身。

希望帮到你。

本文还有配套的精品资源,点击获取

返回列表