基于Python实现网络拓扑实验:从邻接矩阵到可视化与鲁棒性分析
简介这份资源面向计算机网络课程学习者与实验实践者围绕基于Python的网络拓扑实验展开重点解决传输机制实验中拓扑运行与文件收发功能的实现问题。包内共96个文件以C源码与头文件为主体28个.c、40个.h辅以14个Shell脚本、4个Python脚本及Makefile、数据文件、实验报告PDF、演示PPT与说明文档等压缩包约2.65MB结构上按实验阶段与代码版本分目录组织便于对照查阅。实验内容涵盖运行给定网络拓扑tcp_topo.py以及修改tcp_apps.c与tcp_stack.py实现文件收发配套报告与讲义可辅助理解协议栈设计思路。目前已有172人学习适合需要完成课程设计、理解TCP传输机制与网络拓扑搭建的读者参考可从中获取可运行的实验代码、分阶段实现思路与调试排错线索。1. 用 Python 把网络拓扑跑起来从邻接矩阵到可视化一套能复现的最小实验手里只有一台笔记本、一个 Python 环境能不能把「网络拓扑」这件事从抽象概念变成看得见、算得动的东西能。我做过很多次这类实验核心就三件事把拓扑抽象成图、把图存成矩阵或邻接表、再把结果画出来或者算指标。标题里的「基于 Python 实现网络拓扑的实验」本质就是用 Python 的图论工具链把节点和链路的关系建模、计算、可视化最后验证拓扑特性连通性、中心度、最短路径、鲁棒性。它适合两类人一类是刚学完 Python 基础、想找个能落地的练手项目的新手另一类是做运维、网络规划、甚至量化交易里研究关联网络的从业者需要快速验证一个拓扑假设。下面这套流程我在自己机器上反复跑过环境干净、依赖少、每一步都能单独验证。2. 拓扑建模先想清楚节点、边、有向还是无向2.1 网络拓扑在代码里到底长什么样网络拓扑在数学上就是一个图 G(V,E)V 是节点集合E 是边集合。落到 Python 里最常用的两种表示是邻接矩阵和邻接表。邻接矩阵是一个 N×N 的二维数组matrix[i][j]1表示 i 和 j 之间有链路邻接表则是每个节点维护一个邻居列表。选哪个取决于你的拓扑规模和后续要算什么节点数在几百以内、要做矩阵运算比如谱聚类、特征值分析用邻接矩阵节点上千、边稀疏用邻接表省内存。我一般先用邻接矩阵把逻辑跑通因为直观、好调试等规模上来了再换networkx的图对象。这里有个容易翻车的点无向图的邻接矩阵必须对称matrix[i][j]和matrix[j][i]要同时置 1。我见过有人只填了上三角结果算出来的度数是实际的一半排查了半天。有向图则不用对称但要注意入度和出度的区别。另外带权拓扑比如链路延迟、带宽就把 1 换成具体权重0 表示不通。下面这段代码用纯 Python 列表构造一个 6 节点的无向拓扑不依赖任何第三方库方便你先验证逻辑。# 6 节点无向拓扑的邻接矩阵构造 N 6 # 初始化全 0 矩阵 adj [[0] * N for _ in range(N)] # 定义链路(起点, 终点)无向图两个方向都要置 1 edges [(0, 1), (0, 2), (1, 3), (2, 3), (3, 4), (4, 5)] for u, v in edges: adj[u][v] 1 adj[v][u] 1 # 无向图必须对称漏掉这行度数会算错 # 打印矩阵方便肉眼检查 for row in adj: print(row)逻辑说明adj是 N×N 的嵌套列表edges里每条链路都双向赋值保证对称。参数说明N是节点总数改拓扑时同步改edges即可如果是有向图删掉adj[v][u] 1那一行。跑完你应该看到一个对角线为 0、其余对称的 0/1 矩阵。这一步别急着上可视化先把矩阵打印出来核对比后面画图发现错了再回头找要省事得多。2.2 用 networkx 建图比手写矩阵省一半代码纯列表适合理解原理但真要做实验networkx是绕不开的。它把节点、边、属性都封装好了还能直接调最短路径、中心度、连通分量这些算法。安装就一行pip install networkx如果你还要画图再装matplotlib。我一般会同时装这两个画图那步用得上。下面把上面的拓扑用networkx重建并顺手算几个基础指标。import networkx as nx G nx.Graph() # 无向图有向图用 nx.DiGraph() edges [(0, 1), (0, 2), (1, 3), (2, 3), (3, 4), (4, 5)] G.add_edges_from(edges) print(节点数:, G.number_of_nodes()) print(边数:, G.number_of_edges()) print(各节点度数:, dict(G.degree())) print(是否连通:, nx.is_connected(G)) print(平均最短路径长度:, nx.average_shortest_path_length(G))逻辑说明add_edges_from一次性把边列表灌进去节点会自动创建。G.degree()返回每个节点的度is_connected判断整个图是否连通average_shortest_path_length算平均跳数。参数说明nx.Graph()换成nx.DiGraph()就是有向图换成nx.MultiGraph()支持两点间多条链路。这几个指标是拓扑实验的「体检报告」连通性为 False 说明有孤立子图平均路径长度能反映拓扑的紧凑程度。跑通这步你就有了一个可计算、可扩展的拓扑对象后面所有实验都基于它。3. 从矩阵到图可视化与指标计算的完整链路3.1 用 matplotlib 把拓扑画出来节点位置怎么定拓扑画出来才直观但节点位置layout是新手最容易卡住的地方。networkx内置了好几种布局spring_layout模拟弹簧斥力适合一般拓扑circular_layout把节点排成圆适合看环形结构kamada_kawai_layout基于距离画出来的图比较规整。我一般先用spring_layout因为它对大多数拓扑都能给出可读的结果。下面这段代码把图存成 PNG注意matplotlib在无界面环境比如服务器要指定后端否则会报错。import matplotlib matplotlib.use(Agg) # 无界面环境必须加否则 plt.show() 会崩 import matplotlib.pyplot as plt import networkx as nx G nx.Graph() G.add_edges_from([(0, 1), (0, 2), (1, 3), (2, 3), (3, 4), (4, 5)]) pos nx.spring_layout(G, seed42) # seed 固定保证每次布局一致 nx.draw_networkx_nodes(G, pos, node_colorlightblue, node_size500) nx.draw_networkx_edges(G, pos, width1.5) nx.draw_networkx_labels(G, pos, font_size12) plt.axis(off) plt.savefig(topology.png, dpi150, bbox_inchestight) print(已保存 topology.png)逻辑说明spring_layout返回每个节点的 (x, y) 坐标字典seed固定后每次运行布局相同方便对比不同拓扑。draw_networkx_nodes/edges/labels分别画节点、边、标签。参数说明node_size控制节点大小dpi控制输出清晰度bbox_inchestight去掉多余白边。如果你在 Jupyter 里跑把matplotlib.use(Agg)去掉、savefig换成plt.show()即可。画完打开图片先看有没有孤立节点、有没有明显画错的边这一步能帮你抓出建模阶段的低级错误。3.2 中心度与最短路径拓扑实验里最常算的两个指标拓扑实验不只是画图更重要的是算指标。最常用的两个是中心度和最短路径。中心度衡量节点的重要性degree_centrality看连接数betweenness_centrality看节点在多少条最短路径上中介性closeness_centrality看节点到其他节点的平均距离。最短路径则用shortest_path和shortest_path_length。下面这段代码把三个中心度都算出来并找出节点 0 到 5 的最短路径。import networkx as nx G nx.Graph() G.add_edges_from([(0, 1), (0, 2), (1, 3), (2, 3), (3, 4), (4, 5)]) deg_c nx.degree_centrality(G) btw_c nx.betweenness_centrality(G) clo_c nx.closeness_centrality(G) for n in G.nodes(): print(f节点{n}: 度中心度{deg_c[n]:.3f}, f中介中心度{btw_c[n]:.3f}, 接近中心度{clo_c[n]:.3f}) path nx.shortest_path(G, source0, target5) length nx.shortest_path_length(G, source0, target5) print(0 到 5 的最短路径:, path, 长度:, length)逻辑说明三个中心度函数都返回字典键是节点、值是分数。shortest_path返回节点序列shortest_path_length返回跳数。参数说明betweenness_centrality可以加weight参数支持带权图shortest_path默认按跳数算带权图要传weightweight。跑完你会发现节点 3 的中介中心度最高因为它连接了左右两个子图是拓扑里的「咽喉」。这个结论在真实网络里很有用——咽喉节点一旦故障整个网络可能分裂。我一般会把中心度排序后取 Top 3作为重点监控对象。3.3 把邻接矩阵和 networkx 互相转换实际项目里经常需要在两种表示之间切换比如从数据库读出来的是矩阵但算法要用networkx或者用networkx算完要导出成矩阵给别的模块。转换本身不难但有几个细节容易出错。下面这段代码演示双向转换并验证转换前后一致。import networkx as nx import numpy as np # networkx - 邻接矩阵 G nx.Graph() G.add_edges_from([(0, 1), (0, 2), (1, 3), (2, 3), (3, 4), (4, 5)]) mat nx.to_numpy_array(G) print(矩阵形状:, mat.shape) print(mat) # 邻接矩阵 - networkx G2 nx.from_numpy_array(mat) print(还原后边数:, G2.number_of_edges()) print(与原图是否同构:, nx.is_isomorphic(G, G2))逻辑说明to_numpy_array把图转成 numpy 矩阵from_numpy_array反向还原。is_isomorphic验证两个图结构是否一致。参数说明to_numpy_array默认按节点标签排序如果节点标签不是 0 到 N-1 的整数要先G nx.convert_node_labels_to_integers(G)再转否则矩阵行列顺序会对不上。这个坑我踩过——节点标签是字符串时直接转矩阵看着没问题但和原始节点对应关系全乱了。转换完一定要用is_isomorphic验一下这是最省事的后悔药。4. 避坑与排查拓扑实验里最容易翻车的 5 个地方4.1 邻接矩阵不对称导致度数算错现象算出来的节点度数总是实际的一半或者连通性判断为 False。原因无向图只填了上三角adj[i][j]1但adj[j][i]还是 0。解决构造时强制双向赋值或者构造完加一句adj adj adj.Tnumpy 矩阵再检查对角线是否为 0。我现在的习惯是写完矩阵先打印出来肉眼扫一遍对称性比后面算法报错再回头找快得多。4.2 matplotlib 在服务器上报 no display 错误现象本地跑得好好的画图代码放到服务器或 Docker 里就报no display name and no $DISPLAY environment variable。原因matplotlib默认用交互式后端无界面环境没有显示设备。解决在import matplotlib.pyplot之前加matplotlib.use(Agg)强制用非交互后端。注意这行必须在pyplot导入之前顺序反了不生效。如果还要在 Jupyter 里显示就只在服务器脚本里加别写进公共模块。4.3 节点标签不是整数时矩阵行列错位现象用to_numpy_array转出来的矩阵和原始节点对应不上算出来的中心度张冠李戴。原因to_numpy_array默认按节点标签排序字符串标签排序结果和插入顺序不一致。解决转换前先G nx.convert_node_labels_to_integers(G, first_label0)把标签统一成 0 到 N-1转换后再用映射表还原。或者直接用nodelist参数指定顺序nx.to_numpy_array(G, nodelistsorted(G.nodes()))。4.4 spring_layout 每次画出来不一样现象同一个拓扑每次运行画出来的节点位置都不同没法做对比图。原因spring_layout初始位置是随机的。解决加seed参数固定随机种子比如nx.spring_layout(G, seed42)。这样每次布局一致方便把不同拓扑的画图结果并排对比。如果要做论文级别的图还可以先算好pos存成 JSON画图时直接读彻底消除随机性。4.5 大规模拓扑用纯 Python 列表内存爆炸现象节点数上千后邻接矩阵占用内存飙升程序卡死。原因N×N 矩阵的内存是 O(N²)10000 个节点就是 1 亿个元素。解决节点数超过 1000 且边稀疏时改用邻接表或直接上networkx的图对象内部用字典存储内存是 O(NE)。如果必须用矩阵考虑scipy.sparse的稀疏矩阵只存非零元素。我一般以 500 个节点为分界线超过就换稀疏表示。5. 进阶技巧用拓扑鲁棒性实验验证你的网络设计前面都是基础操作真正能体现拓扑实验价值的是鲁棒性分析——模拟节点或边失效看网络会不会分裂。这个技巧在运维容量规划、网络架构评审里特别实用。做法很简单依次移除每个节点重新算连通分量数量和最大连通子图的大小下降越快说明拓扑越脆弱。下面这段代码对 6 节点拓扑做节点移除实验输出每个节点失效后的最大连通子图占比。import networkx as nx G nx.Graph() G.add_edges_from([(0, 1), (0, 2), (1, 3), (2, 3), (3, 4), (4, 5)]) N G.number_of_nodes() print(节点移除鲁棒性分析) for node in list(G.nodes()): H G.copy() H.remove_node(node) if H.number_of_nodes() 0: print(f移除节点{node}: 网络完全消失) continue largest max(nx.connected_components(H), keylen) ratio len(largest) / N print(f移除节点{node}: 最大连通子图占比{ratio:.2f}, f连通分量数{nx.number_connected_components(H)})逻辑说明每次复制原图、移除一个节点然后算最大连通子图占原节点总数的比例。占比越低说明该节点越关键。参数说明connected_components返回连通分量的节点集合max(..., keylen)取最大的那个。跑完你会看到移除节点 3 后占比明显下降因为它连接左右两个子图。这个实验可以扩展到边移除、随机失效、按中心度排序失效等多种策略。我一般会把结果画成折线图横轴是移除节点数纵轴是最大连通子图占比曲线下降越陡说明拓扑越脆弱。这个技巧的价值在于它把「拓扑设计好不好」从主观判断变成了可量化对比。你可以设计两套拓扑方案分别跑鲁棒性实验看哪套在关键节点失效后仍能保持连通。我自己的习惯是任何拓扑方案上线前都跑一遍这个实验把最脆弱的三个节点标出来作为冗余设计的重点。这套流程不依赖任何外部服务纯 Python 加networkx就能跑适合反复迭代。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

Shell 编程流程控制全实战|曼巴精神打磨运维自动化核心功

Shell 编程流程控制全实战|曼巴精神打磨运维自动化核心功

文章目录一、if 条件语句|运维最常用的判断三种结构1. 单分支:满足就干2. 双分支:满足干这个,不满足干那个3. 多分支:多个条件挨个匹配条件表达式的五种写法生产经典实战示例 1:监控 sshd 服务,…

2026/10/11 7:08:38 阅读更多 →
喜鹊DLSS5与RESHADE模拟DLSS5技术路线深度对比

喜鹊DLSS5与RESHADE模拟DLSS5技术路线深度对比

1. 项目概述:一场关于画质增强技术实现路径的实测对话最近在多个图形技术交流群和硬件爱好者论坛里,频繁看到“喜鹊DLSS5”和“RESHADE渲染中DLSS5”这两个词被并列讨论,甚至有人直接打出“喜鹊大胜特胜,谁说外置不如注入&#xf…

2026/10/11 7:08:38 阅读更多 →
鸿蒙端侧AI导览实战:离线多模态智能导游开发指南

鸿蒙端侧AI导览实战:离线多模态智能导游开发指南

1. 项目概述:一次真实可复现的端侧AI导览实践“鸿蒙AI:国庆我在故宫用了把‘AI 导游’”——这个标题不是营销噱头,而是我今年国庆假期在某历史文化园区实测落地的一个轻量级智能导览原型。它不依赖云端API调用、不上传用户位置与语音、不联网…

2026/10/11 7:08:38 阅读更多 →

最新新闻

告别语义漂移:用 BM25 与向量检索打造个人日记的混合召回(Hybrid Search)

告别语义漂移:用 BM25 与向量检索打造个人日记的混合召回(Hybrid Search)

秋雨淅淅沥沥下了一整天,空气里泛着潮湿的泥土香气。我坐在书房里,试图从这几年积攒的上千篇日记与手账随笔中,找出一年前在某家咖啡馆尝过的“桂花乌龙生椰拿铁”。 我在私有 RAG 助手里键入了这几个字,屏幕很快吐出了一堆相关记…

2026/10/11 7:52:03 阅读更多 →
轻薄笔记本上的显存天平:Q4_K_M 与 Q8_0 量化实测与生活化选型指南

轻薄笔记本上的显存天平:Q4_K_M 与 Q8_0 量化实测与生活化选型指南

秋风吹得窗台上的绿植沙沙作响,泡上一壶热白茶,把轻薄笔记本放在膝头,是在这个季节里最舒适的姿势。对于喜欢在本地掌控一切数据的开发者来说,轻薄本的安静与便携是一种难得的惬意。但这份惬意往往在打开模型下载列表的一瞬间&…

2026/10/11 7:52:03 阅读更多 →
【计算机毕业设计单片机案例】基于WIFI的自行车骑行速度里程定位远程监测装置设计 基于单片机的骑行速度里程与GPS定位联合采集系统设计(030205)

【计算机毕业设计单片机案例】基于WIFI的自行车骑行速度里程定位远程监测装置设计 基于单片机的骑行速度里程与GPS定位联合采集系统设计(030205)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于嵌入式单片机,Java、小程序技术领域和毕业项目实战 ✌️…

2026/10/11 7:52:03 阅读更多 →
WorkBuddy FDE:90天从需求到真实用户交付路径

WorkBuddy FDE:90天从需求到真实用户交付路径

1. 这不是“从0到1”,而是“从一句话到真用户”的真实压缩路径“WorkBuddy FDE”这个名称本身就很说明问题——它不叫“WorkBuddy Pro”或“WorkBuddy AI”,而是一个带明确角色后缀的缩写。FDE,即 Frontend Developer(前端开发者&…

2026/10/11 7:52:03 阅读更多 →
从模糊需求到90天上线:WorkBuddy FDE方法论实战手册

从模糊需求到90天上线:WorkBuddy FDE方法论实战手册

我接到 WorkBuddy 这个项目时,需求文档只有一句话:做一个能帮团队把任务理清楚的 App。没有用户画像,没有流程图,没有竞品分析,甚至没人说清楚要先做手机版还是网页版。我当时的反应是:这个项目如果直接动手…

2026/10/11 7:52:03 阅读更多 →
NMODBUS 工业通信实战:.NET 下 Modbus TCP/RTU 开发与避坑指南

NMODBUS 工业通信实战:.NET 下 Modbus TCP/RTU 开发与避坑指南

简介:NMODBUS.zip 是一套面向 C# 开发者的 MODBUS TCP/IP 通信库资源,适合刚接触工业自动化协议、需要快速与 PLC 建立数据交互的新手与中级开发者。它封装了 ModbusTcpMaster 等核心类,提供读写保持寄存器、线圈以及数据转换、异常处理等常用…

2026/10/11 7:51:03 阅读更多 →

日新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/11 0:00:27 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/11 0:00:27 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 5:23:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 21:32:20 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 10:38:42 阅读更多 →