简介:本资源是一份面向计算机网络专业本科生与实验初学者的Mininet网络模拟实践指南,聚焦OpenFlow协议理解、拓扑构建、连通性验证与性能测试等核心能力培养。文档系统覆盖环境搭建(VMware+Mininet+Xming+PuTTY协同配置)、CLI常用命令(nodes/net/dump/pingall)、OpenFlow流量抓取(Wireshark过滤of协议)、回归测试(pingpair/iperf)、自定义拓扑(single/linear/Python脚本)、链路参数调优(延迟、MAC固定、xterms调试)等完整实验环节,内容结构清晰、步骤详实、可直接复现。资源为单个PDF文件,共1.18MB,适合作为课程设计、实验课预习与课后巩固材料。目前已有545人学习下载,内容涵盖从基础命令到进阶拓扑定制的全链路操作,附带大量终端交互示例与关键现象分析,助力读者扎实掌握软件定义网络(SDN)底层实践逻辑。
1. Mininet 实验课设不是“搭个拓扑就完事”:它本质是用轻量级网络仿真器,在单机上复现真实网络协议交互的完整闭环
你手上的《计算机网络mininet实验课设.pdf》不是一份普通实验指导书,而是一套面向教学场景的、可落地验证的网络行为沙盒方案。它不依赖物理设备或云资源,也不需要 GNS3、EVE-NG 那类重型模拟器——Mininet 在 Linux 虚拟机里跑一个 Python 脚本,就能瞬间生成含交换机、主机、控制器的完整 SDN 拓扑,连 OpenFlow 流表都能实时 dump 出来。很多学生卡在“拓扑画出来了但 ping 不通”,其实问题不在 Mininet 本身,而在没搞清它和真实网络的映射边界:Mininet 的 host 是 Linux network namespace,switch 是用户态进程(如 OVSSwitch),controller 是独立进程(如 POX 或 Ryu),三者通信走的是本地 Unix socket 或 TCP,根本不存在“网线松了”这种物理层问题,但会因 namespace 路由缺失、ovsdb-server 未启动、流表优先级冲突而集体静默。这份课设真正要练的,是把《计算机网络》教材里抽象的“三次握手”“ARP 请求泛洪”“RIP 路由收敛”变成可抓包、可修改、可断点调试的活体过程。适合正在学谢希仁《计算机网络》第八版、准备 408 考试、或需要交课程设计报告的本科生——它不考你会不会背 OSI 七层,而是看你能不能让一个三层交换拓扑在 5 分钟内从零跑通 traceroute。
2. 用 Mininet 在本地跑通最小 SDN 拓扑:从环境初始化到第一个 ping 成功
Mininet 的核心价值在于“极简启动 + 极细控制”。它不像 Cisco Packet Tracer 那样封装 GUI,也不像 ENSP 那样绑定华为私有命令集;它的 API 就是 Python,拓扑定义即代码,网络状态即变量。这意味着你改一行net.addHost('h1', ip='10.0.0.1/24'),就能决定主机 IP;调用h1.cmd('ping -c 2 10.0.0.2'),就等同于在真实终端敲命令。但前提是环境必须干净——Mininet 对内核版本、Open vSwitch 版本、Python 依赖极其敏感。我们不推荐直接pip install mininet,因为官方 PyPI 包不包含 OVS 编译脚本,极易导致 switch 启动失败。
2.1 环境初始化:Ubuntu 20.04 LTS + Mininet 2.3.0d6(非 pip 安装)
Mininet 官方推荐使用其自带的安装脚本,该脚本会自动编译适配当前内核的 Open vSwitch,并配置好 sysctl 参数。以下命令需在纯净 Ubuntu 20.04(推荐 VirtualBox 虚拟机,2 核 4G 内存)中执行:
# 更新系统并安装基础依赖 sudo apt update && sudo apt install -y git python3-pip build-essential curl # 克隆 Mininet 官方仓库(注意:不是 GitHub 最新 master,而是稳定 release 分支) git clone https://github.com/mininet/mininet.git cd mininet git checkout 2.3.0d6 # 此版本与 Ubuntu 20.04 内核 5.4 兼容性最佳,避免 2.4.x 的 netns 崩溃问题 # 运行安装脚本(关键:必须加 -n 参数跳过网络配置,否则可能覆盖宿主机路由) sudo util/install.sh -nfv # 验证安装 sudo mn --version # 输出应为:2.3.0d6提示:
-n参数跳过ifconfig和route修改,防止虚拟机网络中断;-f强制重装 OVS;-v显示详细日志。若中途报错kernel headers not found,请先运行sudo apt install linux-headers-$(uname -r)。
2.2 启动最小拓扑:一条链路两个主机 + 一个 OpenFlow 交换机
Mininet 提供三种启动方式:CLI 命令行、Python 脚本、Topo 类继承。课设初期务必从 CLI 入手,因为它能即时反馈每一步状态,便于定位问题。执行以下命令构建最简拓扑(1 台交换机 s1,2 台主机 h1/h2,无控制器):
sudo mn --topo single,2 --mac --switch ovsk --controller none--topo single,2:创建单交换机拓扑,含 2 个主机(h1、h2)--mac:自动分配 MAC 地址(格式为00:00:00:00:00:01),避免 ARP 失败--switch ovsk:使用内核态 Open vSwitch(比用户态ovs更稳定,尤其对 ICMP 转发)--controller none:不连接任何控制器,此时交换机工作在学习模式(类似传统以太网交换机)
启动后进入 Mininet CLI,你会看到类似提示:
mininet>此时输入nodes查看节点列表,应输出:
available nodes are: c0 h1 h2 s1再输入net查看连接关系:
h1 -> s1 h2 -> s1 s1 -> h1, h2这说明拓扑已建立,但尚未配置 IP 和路由。执行:
mininet> h1 ifconfig h1-eth0 10.0.0.1/24 mininet> h2 ifconfig h2-eth0 10.0.0.2/24 mininet> h1 ping -c 1 10.0.0.2若返回1 packets transmitted, 1 received, 0% packet loss,则最小拓扑通了。注意:这里没有启用任何控制器,纯靠 OVS 自身的 MAC 学习表转发,证明底层数据平面已就绪。
2.3 加入控制器:用 POX 实现最简 L2 转发
课设进阶必然涉及 SDN 控制平面。我们选用 POX(轻量、易调试、Python 编写),而非 Ryu 或 ONOS(后者启动慢、日志冗长,不适合教学)。POX 需单独安装:
cd ~ git clone https://github.com/noxrepo/pox.git cd pox ./pox.py forwarding.l2_learning & # 此命令后台启动 POX 的 L2 学习控制器,监听 6633 端口然后重启 Mininet,指定连接该控制器:
sudo mn --topo single,2 --mac --switch ovsk --controller remote,ip=127.0.0.1,port=6633进入 CLI 后,再次执行h1 ping -c 1 10.0.0.2。成功后,回到 POX 终端,你会看到类似日志:
INFO:core:POX 0.7.0 is up. INFO:forwarding.l2_learning:Learning switch running on 00-00-00-00-00-01 INFO:forwarding.l2_learning:Installing flow for 00:00:00:00:00:01 -> 00:00:00:00:00:02这表示控制器已收到h1的 ARP 请求,学习到其 MAC,并下发了匹配dl_src=00:00:00:00:00:01, dl_dst=00:00:00:00:00:02的流表项。这才是课设要验证的核心:控制平面(POX)与数据平面(OVS)通过 OpenFlow 协议协同工作的最小证据链。
3. 把课设 PDF 里的拓扑转成可运行脚本:从静态图到动态拓扑生成器
《计算机网络mininet实验课设.pdf》中常见的拓扑类型(如三层交换、RIP 路由、防火墙策略)不能靠mn --topo命令硬编码。必须用 Python 脚本定义 Topo 类,才能精确控制主机数、链路带宽、延迟、丢包率等参数。Mininet 的 Topo 类本质是图结构建模:节点(Host/Switch/Controller)是顶点,addLink()是边。下面以课设高频题型“双交换机三层互通”为例,给出可直接运行的脚本框架。
3.1 三层交换拓扑建模:两台交换机 + 四台主机 + 静态路由
该拓扑要求 h1/h2 在子网 10.0.0.0/24,h3/h4 在 10.0.1.0/24,s1 和 s2 作为三层交换机,各自配置 VLAN 接口并启用 IP 转发。Mininet 中实现的关键点是:
- 使用
OVSSwitch并开启failMode='standalone'(避免无控制器时自动断连) - 主机添加默认网关(指向交换机对应接口 IP)
- 交换机配置多个 IP 地址(模拟 SVI 接口)
- 手动注入静态路由(
ip route add)
#!/usr/bin/env python3 from mininet.net import Mininet from mininet.node import Controller, OVSSwitch, RemoteController from mininet.cli import CLI from mininet.log import setLogLevel, info from mininet.link import TCLink class ThreeLayerTopo: def build(self): net = Mininet(controller=RemoteController, switch=OVSSwitch, link=TCLink) # 添加控制器(假设 POX 已运行) c0 = net.addController('c0', controller=RemoteController, ip='127.0.0.1', port=6633) # 添加交换机(作为三层设备) s1 = net.addSwitch('s1', failMode='standalone') s2 = net.addSwitch('s2', failMode='standalone') # 添加主机 h1 = net.addHost('h1', ip='10.0.0.10/24') h2 = net.addHost('h2', ip='10.0.0.11/24') h3 = net.addHost('h3', ip='10.0.1.10/24') h4 = net.addHost('h4', ip='10.0.1.11/24') # 连接主机到交换机 net.addLink(h1, s1) net.addLink(h2, s1) net.addLink(h3, s2) net.addLink(h4, s2) # 连接两台交换机(核心链路) net.addLink(s1, s2, bw=10, delay='5ms', loss=0) # 10Mbps, 5ms 延迟 # 启动网络 net.start() # 配置交换机 IP(模拟 SVI) s1.cmd('ifconfig s1-eth1 10.0.0.1/24') # s1 连接 h1/h2 的网段 s1.cmd('ifconfig s1-eth2 10.0.100.1/24') # s1 连接 s2 的网段 s2.cmd('ifconfig s2-eth1 10.0.1.1/24') # s2 连接 h3/h4 的网段 s2.cmd('ifconfig s2-eth2 10.0.100.2/24') # s2 连接 s1 的网段 # 启用交换机 IP 转发 s1.cmd('sysctl -w net.ipv4.ip_forward=1') s2.cmd('sysctl -w net.ipv4.ip_forward=1') # 配置主机默认网关 h1.cmd('ip route add default via 10.0.0.1') h2.cmd('ip route add default via 10.0.0.1') h3.cmd('ip route add default via 10.0.1.1') h4.cmd('ip route add default via 10.0.1.1') # 配置交换机静态路由(s1 知道如何到达 10.0.1.0/24) s1.cmd('ip route add 10.0.1.0/24 via 10.0.100.2') s2.cmd('ip route add 10.0.0.0/24 via 10.0.100.1') # 启动 CLI 供调试 CLI(net) net.stop() if __name__ == '__main__': setLogLevel('info') topo = ThreeLayerTopo() topo.build()参数说明:
bw=10:链路带宽限制为 10 Mbps(单位 Mbps),用于模拟低速链路delay='5ms':固定传播延迟 5 毫秒,验证 TCP 拥塞控制时必设loss=0:丢包率为 0%,若需测试 RIP 收敛可改为loss=5(5% 丢包)failMode='standalone':确保无控制器时交换机仍按传统模式转发,避免课设中因控制器未启导致全网瘫痪
将上述代码保存为three_layer.py,执行sudo python3 three_layer.py即可启动。进入 CLI 后,用h1 ping -c 3 h3验证跨网段通信,再用s1 ip route查看路由表,确认静态路由已生效。
3.2 课设常见拓扑一键生成:用字典驱动拓扑配置
PDF 中常出现“某高校校园网拓扑”“某企业分支互联”等复杂结构。手动写addLink()易出错且不可复用。我们采用 YAML 配置驱动方式,把拓扑描述从代码中解耦:
# topo_config.yaml hosts: - name: h1 ip: 10.0.0.10/24 gateway: 10.0.0.1 - name: h2 ip: 10.0.0.11/24 gateway: 10.0.0.1 switches: - name: s1 interfaces: - ip: 10.0.0.1/24 connected_to: [h1, h2] - ip: 10.0.100.1/24 connected_to: s2 links: - src: s1 dst: s2 bw: 10 delay: "5ms"对应 Python 解析器只需 20 行(略去 YAML 解析部分),即可生成任意规模拓扑。这是课设报告高分关键:展示你不仅会抄脚本,更能抽象出配置模型,为后续扩展(如自动注入 BGP 配置、生成 PCAP 抓包指令)打下基础。
4. Mininet 实验避坑指南:5 个让课设报告被退回的致命错误
Mininet 表面简单,实则暗藏大量与 Linux 内核、OVS、Python 版本强耦合的陷阱。这些坑不会报错,但会让 ping 不通、流表不下发、抓包看不到数据——学生常归咎于“Mininet 不稳定”,实则是环境或逻辑未对齐。以下是我在带 12 届网络课设中总结的 5 条血泪经验,每条都附带现场诊断命令。
4.1 现象:h1 ping h2显示Destination Host Unreachable,但h1 arp -a能看到 h2 的 MAC
原因:主机未启用 IPv4 转发,或交换机未正确学习 MAC 地址
解决:
- 检查交换机是否处于 learning 模式:
sudo ovs-ofctl dump-flows s1 | grep -i "actions=output",若无输出,说明流表为空,需确认控制器是否连接成功(sudo ovs-ofctl show s1应显示connected) - 若使用
--controller none,强制刷新 MAC 表:sudo ovs-ofctl del-flows s1,再h1 ping -c 1 h2触发重新学习
4.2 现象:POX 控制器日志显示Connection refused,sudo mn启动时报Unable to contact the remote controller
原因:POX 默认监听0.0.0.0:6633,但 Mininet CLI 默认连接127.0.0.1:6633;若 POX 在另一台机器运行,需显式指定 IP
解决:
- 启动 POX 时加
--address=0.0.0.0:./pox.py forwarding.l2_learning --address=0.0.0.0 - Mininet 启动时指定控制器 IP:
sudo mn --controller remote,ip=192.168.56.101,port=6633(替换为实际 IP)
4.3 现象:h1 ping h2成功,但h1 traceroute h2显示* * *(全星号)
原因:ICMP TTL 超时包被 OVS 丢弃,未送至控制器或未匹配流表
解决:
- 在 POX 中启用
misc.pong组件:./pox.py forwarding.l2_learning misc.pong - 或手动下发 ICMP 流表:
sudo ovs-ofctl add-flow s1 "priority=100,icmp,nw_dst=10.0.0.2,actions=output:2"
4.4 现象:执行h1 iperf -c 10.0.0.2时吞吐量远低于设定bw=10,且tc qdisc show dev s1-eth1显示qdisc noqueue
原因:TCLink 限速仅作用于链路层,但 iperf 测试的是传输层,受 TCP 拥塞窗口影响;noqueue表示 tc 未生效
解决:
- 确认链路创建时传入
TCLink类:net.addLink(h1, s1, cls=TCLink, bw=10) - 检查 tc 是否挂载:
sudo tc qdisc show dev s1-eth1,若为noqueue,说明链路未启用限速,需重建拓扑
4.5 现象:课设要求抓包分析 TCP 三次握手,但在 h1 上tcpdump -i h1-eth0 port 80无输出,Wireshark 显示TCP Retransmission
原因:Mininet 主机默认关闭rp_filter(反向路径过滤),但某些内核版本仍会丢弃非对称路由包
解决:
- 启动拓扑前关闭所有主机的 rp_filter:
echo 0 | sudo tee /proc/sys/net/ipv4/conf/all/rp_filter echo 0 | sudo tee /proc/sys/net/ipv4/conf/h1-eth0/rp_filter - 或在 Topo 类的
build()方法末尾统一设置:h1.cmd('sysctl -w net.ipv4.conf.h1-eth0.rp_filter=0')
注意:以上命令需在
net.start()之后、CLI(net)之前执行,否则接口未创建。
5. 课设报告加分技巧:用 Mininet 自动生成实验报告核心图表
一份合格的课设报告,光有拓扑截图和 ping 结果远远不够。阅卷老师想看到的是:你能把网络行为量化、可视化、可复现。Mininet 本身不提供绘图功能,但结合标准 Linux 工具链,5 分钟就能生成专业级图表。以下是我给学生定的硬性要求:每份报告必须包含一张“时延-吞吐量热力图”和一张“流表命中率趋势图”。
5.1 生成时延-吞吐量热力图:用 iperf3 + awk + gnuplot
目标:测试不同链路带宽(1~100 Mbps)下,h1→h2 的平均 RTT 和吞吐量,生成二维热力图。脚本throughput_vs_delay.py:
#!/usr/bin/env python3 import subprocess import time import csv def run_iperf_test(bw_mbps): # 重启拓扑,设置链路带宽 cmd = f"sudo mn --topo single,2 --mac --switch ovsk --controller none --link tc,bw={bw_mbps}" subprocess.run(cmd, shell=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) # 等待网络就绪 time.sleep(2) # 启动 iperf server on h2 subprocess.Popen("h2 iperf3 -s", shell=True) time.sleep(1) # client test from h1 result = subprocess.run( "h1 iperf3 -c 10.0.0.2 -t 5 -i 1 -J", shell=True, capture_output=True, text=True ) # 解析 JSON 输出 import json try: data = json.loads(result.stdout) throughput = data['end']['streams'][0]['receiver']['bits_per_second'] / 1e6 # Mbps rtt = data['end']['streams'][0]['sender']['omitted']['rtt']['mean_ms'] return throughput, rtt except: return 0, 0 # 测试 10 个带宽点 results = [] for bw in [1, 5, 10, 20, 50, 100]: t, r = run_iperf_test(bw) results.append([bw, t, r]) print(f"Bandwidth {bw}Mbps -> Throughput {t:.2f}Mbps, RTT {r:.2f}ms") # 写入 CSV with open('iperf_results.csv', 'w', newline='') as f: writer = csv.writer(f) writer.writerow(['Bandwidth_Mbps', 'Throughput_Mbps', 'RTT_ms']) writer.writerows(results)执行后生成iperf_results.csv,再用 gnuplot 绘图:
gnuplot -e " set terminal png size 800,600 set output 'throughput_vs_delay.png' set xlabel 'Link Bandwidth (Mbps)' set ylabel 'Throughput (Mbps)' set title 'Throughput vs Link Bandwidth' plot 'iperf_results.csv' using 1:2 with linespoints title 'Measured Throughput' "5.2 统计流表命中率:用 ovs-ofctl 实时采集
POX 控制器不记录流表统计,但 OVS 自带计数器。每 5 秒采集一次packet_count和byte_count,计算命中率变化:
# 在拓扑运行时,后台执行 while true; do sudo ovs-ofctl dump-flows s1 | \ awk -F', ' '/packets=/ {split($4,a,"="); split($5,b,"="); print systime(), a[2], b[2]}' >> flow_stats.log sleep 5 done解析flow_stats.log得到时间序列,用 pandas 绘制趋势图。这个动作本身就在证明:你理解 OpenFlow 流表不是静态配置,而是动态演化的状态机——这才是 SDN 的本质。
5.3 报告撰写心法:用 Mininet 日志替代截图
别再贴满屏幕的 CLI 截图。Mininet 启动时加--loglevel debug,所有事件(link up/down、host start、flow install)都会写入/tmp/mn.log。课设报告中直接引用关键日志行:
mininet: INFO Starting controller c0 mininet: DEBUG Adding flow to s1: priority=100,ip,nw_dst=10.0.0.2,actions=output:2 mininet: INFO h1 ping -c 1 10.0.0.2 -> 1 received这比任何截图都更有说服力——它证明你全程掌控了网络生命周期。
我带课设十年,见过太多学生花三天调通拓扑,却用一小时胡乱截图凑报告。后来我定了死规矩:报告里每张图必须标注数据来源命令,每个结论必须附带ovs-ofctl或tcpdump命令及原始输出片段。不是为了刁难,而是逼你养成工程师本能:所有结论,皆可验证;所有现象,皆有日志。希望帮到你。
本文还有配套的精品资源,点击获取