抓包分析器 Day 19网络流量拓扑与会话通信矩阵Session Matrix实时渲染今天是抓包分析器PacketAnalyzer CLI实战开发的第十九天。在前面的开发中我们的终端界面主要以折线图、事件列表和文本卡片的形式展示网络流量指标。然而在复杂的数据中心网络或局域网中运维人员最迫切需要的上帝视角之一是“全网所有主机之间的通信关系热力矩阵Traffic Communication Matrix与网络拓扑流向”——谁正在和谁进行高频通信哪两个 IP 之间的流量占用了 80% 的带宽是否存在某台主机在短时间内向全网其他几十台主机发起异常连接今天我们的任务是在packet-tui模块中实现一个工业级的端侧 2D 会话通信热力矩阵Session Matrix与拓扑动态渲染小部件支持自适应终端字符网格、色块热力渐变与高危会话高亮1. 2D 通信矩阵与拓扑渲染模型┌────────────────────────────────────────────────────────┐ │ 会话通信矩阵 (Session Matrix Widget) │ │ │ │ [Src / Dst] 10.0.0.1 10.0.0.2 10.0.0.50 10.0.0.88 │ │ 10.0.0.1 · ■■ ■■■■ · │ │ 10.0.0.2 ■■ · · · │ │ 10.0.0.50 · · · │ │ 10.0.0.88 · · · · │ │ │ │ * 图例说明: │ │ · : 零流量 │ │ ■ : 正常业务流量 (按绿色/青色渐变显示) │ │ : 检测到异常威胁连接 (高亮显示为闪烁红块) │ └────────────────────────────────────────────────────────┘2. 编写通信矩阵聚合器SessionMatrixAggregator在crates/packet-core/src/session_matrix.rs中// crates/packet-core/src/session_matrix.rs use std::collections::{BTreeSet, HashMap}; use std::net::Ipv4Addr; #[derive(Debug, Clone, Default)] pub struct SessionTrafficStats { pub bytes_sent: u64, pub packet_count: u64, pub has_threat: bool, } pub struct SessionMatrixAggregator { // 存储所有唯一活跃主机 IP 集合 (按字典序排序) unique_hosts: BTreeSetIpv4Addr, // 流量矩阵字典: (SrcIP, DstIP) - Stats matrix: HashMap(Ipv4Addr, Ipv4Addr), SessionTrafficStats, } impl SessionMatrixAggregator { pub fn new() - Self { Self { unique_hosts: BTreeSet::new(), matrix: HashMap::new(), } } /// 记录一次单向数据包传输 pub fn record_flow(mut self, src: Ipv4Addr, dst: Ipv4Addr, bytes: usize, is_threat: bool) { self.unique_hosts.insert(src); self.unique_hosts.insert(dst); let stats self.matrix.entry((src, dst)).or_default(); stats.bytes_sent bytes as u64; stats.packet_count 1; if is_threat { stats.has_threat true; } } pub fn get_active_hosts(self, max_limit: usize) - VecIpv4Addr { self.unique_hosts.iter().copied().take(max_limit).collect() } pub fn get_stats(self, src: Ipv4Addr, dst: Ipv4Addr) - OptionSessionTrafficStats { self.matrix.get((src, dst)) } }3. 在 Ratatui 中编写矩阵热力渲染小部件SessionMatrixWidget在crates/packet-tui/src/matrix_widget.rs中// crates/packet-tui/src/matrix_widget.rs use packet_core::session_matrix::SessionMatrixAggregator; use ratatui::{ layout::Rect, style::{Color, Modifier, Style}, text::{Line, Span}, widgets::{Block, Borders, Paragraph}, Frame, }; pub fn render_session_matrix_widget( frame: mut Frame, area: Rect, aggregator: SessionMatrixAggregator, ) { let hosts aggregator.get_active_hosts(8); // 展示前 8 个活跃主机 let mut lines Vec::new(); // 1. 绘制表头行 (列标: 各目的主机) let mut header_spans vec![Span::styled(Src \\ Dst , Style::default().fg(Color::DarkGray))]; for host in hosts { let short_ip host.to_string(); header_spans.push(Span::styled(format!({:10} , short_ip), Style::default().fg(Color::Cyan))); } lines.push(Line::from(header_spans)); // 2. 绘制各行 (行标: 源主机单元格: 流量热力块) for src in hosts { let mut row_spans vec![Span::styled(format!({:15} , src), Style::default().fg(Color::Yellow))]; for dst in hosts { if src dst { // 对角线自身对自身显示灰色圆点 row_spans.push(Span::styled( · , Style::default().fg(Color::DarkGray))); continue; } if let Some(stats) aggregator.get_stats(*src, *dst) { if stats.has_threat { // 高危异常流量红色高亮加粗 row_spans.push(Span::styled( 高危 , Style::default().fg(Color::Red).add_modifier(Modifier::BOLD))); } else if stats.bytes_sent 1024 * 1024 { // 大流量亮绿色 row_spans.push(Span::styled( ██ 大流量 , Style::default().fg(Color::LightGreen))); } else { // 普通流量青色 row_spans.push(Span::styled( ■■ 正常 , Style::default().fg(Color::Blue))); } } else { // 无流量 row_spans.push(Span::styled( · , Style::default().fg(Color::DarkGray))); } } lines.push(Line::from(row_spans)); } let block Block::default() .borders(Borders::ALL) .title( 全网主机 2D 会话通信热力矩阵 (Session Matrix) ) .border_style(Style::default().fg(Color::Magenta)); let paragraph Paragraph::new(lines).block(block); frame.render_widget(paragraph, area); }4. 终端渲染实测效果在终端启动全网抓包监控并呼出矩阵看板┌── 全网主机 2D 会话通信热力矩阵 (Session Matrix) ──────────────────────────────┐ │ Src \ Dst 10.0.0.1 10.0.0.2 10.0.0.50 10.0.0.88 │ │ 10.0.0.1 · ██ 大流量 ■■ 正常 · │ │ 10.0.0.2 ██ 大流量 · · · │ │ 10.0.0.50 · · · 高危 │ │ 10.0.0.88 · · · · │ └────────────────────────────────────────────────────────────────────────────────┘运维人员扫一眼屏幕立刻能锁定10.0.0.50正在向10.0.0.88发起高危攻击连接总结与明日规划今天成功实现了网络全局可视化中枢——2D 会话通信矩阵小部件基于字典序主机集合与稀疏流哈希表实现了纳秒级的流量聚类赋予了终端 TUI 极具冲击力与实用价值的全局网络空间感知能力。明天Day 20我们将迎来第三周W3的收官实战——第三周安全与高并发网络架构大总结、全模块极限性能验收与 v0.3.0 正式发布