15 KiB
LogCap 项目分析文档
1. 项目概述
LogCap 是一个专门用于抓取、分析 UDP 数据包并通过 MQTT 协议发送分析结果的网络监控工具。该项目主要用于监控和分析网络设备的通信数据,特别是针对特定协议的设备注册、心跳和状态上报等数据包。
1.1 主要功能
- 网络数据包抓取:使用 SharpPcap 库实时抓取网络接口上的 UDP 数据包
- 数据包分析:解析 UDP 数据包内容,提取设备信息、命令类型等关键数据
- MQTT 数据发送:将分析结果通过 MQTT 协议发送到指定的 MQTT 服务器
- 端点监控:监控特定 IP 和端口的通信情况
- 设备管理:处理设备注册、心跳包等特殊数据包
- 缓存管理:使用内存缓存存储设备信息,提高处理效率
1.2 技术栈
- 开发语言:C#
- 框架:.NET
- 网络抓包:SharpPcap
- MQTT 客户端:MQTTnet
- JSON 序列化:Newtonsoft.Json
- HTTP 客户端:RestSharp
- 缓存:MemoryCache、CSRedis
2. 项目结构
LogCap 项目采用模块化设计,将不同功能分散到不同的类和文件中,提高了代码的可维护性和可读性。
LogCap/
├── Common/ # 核心功能模块
│ ├── CSRedisCacheHelper.cs # Redis 缓存辅助类
│ ├── CacheKey.cs # 缓存键定义
│ ├── DealWithData.cs # 数据包处理逻辑
│ ├── HttpSend.cs # MQTT 数据发送
│ ├── LogExecute.cs # 数据包抓取和处理
│ ├── PubRepository.cs # 设备管理和监控控制
│ ├── ReadConfig.cs # 配置文件读取
│ └── TCache.cs # 缓存管理
├── Entity/ # 数据模型
│ └── Monitor_Host.cs # 监控主机模型
├── Properties/ # 项目属性
├── Program.cs # 主程序入口
├── LogCap.csproj # 项目文件
├── app.json # 配置文件
└── nlog.config # 日志配置
3. 核心功能模块
3.1 数据包抓取与分析
功能说明:使用 SharpPcap 库抓取网络接口上的 UDP 数据包,并对数据包进行解析和分析。
实现逻辑:
- 在
LogExecute.cs中,通过Execute方法初始化网络设备并设置过滤器 - 注册
device_OnPacketArrival事件处理程序,当有数据包到达时触发 - 在事件处理程序中,解析数据包,提取源/目标 IP、端口和数据内容
- 调用
DealWithData.HandleData方法处理数据包内容
关键代码:
// LogExecute.cs: 设备数据包到达事件处理
private static void device_OnPacketArrival(object sender, PacketCapture e)
{
try
{
var rawPacket = e.GetPacket();
var p = Packet.ParsePacket(rawPacket.LinkLayerType, rawPacket.Data);
// 提取 IP 地址和端口
IPAddress SourceAddress = ((PacketDotNet.IPv4Packet)pff).SourceAddress;
ushort SourcePort = ((PacketDotNet.UdpPacket)((PacketDotNet.IPPacket)pff).PayloadPacket).SourcePort;
var DestinationAddress = ((PacketDotNet.IPv4Packet)pff).DestinationAddress;
ushort DestinationPort = ((PacketDotNet.UdpPacket)((PacketDotNet.IPPacket)pff).PayloadPacket).DestinationPort;
// 提取数据内容
byte[] Data = ((PacketDotNet.IPPacket)pff).PayloadPacket.PayloadData;
// 异步处理数据
Tuple<byte[], IPAddress, ushort, IPAddress, ushort> ddd = new Tuple<byte[], IPAddress, ushort, IPAddress, ushort>(Data, SourceAddress, SourcePort, DestinationAddress, DestinationPort);
Task.Factory.StartNew((State) =>
{
var tf = State as Tuple<byte[], IPAddress, ushort, IPAddress, ushort>;
DealWithData.HandleData(tf.Item1.ToList(), tf.Item2.ToString(), tf.Item3, tf.Item4.ToString(), tf.Item5);
}, ddd);
}
catch (Exception ex)
{
// 异常处理
}
}
3.2 数据包处理与解析
功能说明:解析 UDP 数据包内容,提取设备信息、命令类型等关键数据,并根据数据包类型进行相应处理。
实现逻辑:
- 在
DealWithData.cs中,HandleData方法接收数据包内容和网络信息 - 解析数据包头部,提取命令类型、项目代码等信息
- 根据命令类型(注册、心跳、设备状态等)进行不同处理
- 调用
ReallyDealWith方法处理具体业务逻辑
关键代码:
// DealWithData.cs: 处理数据包
public static void HandleData(List<byte> data, string source_ip, ushort source_port, string dest_ip, ushort dest_port)
{
try
{
// 解析数据包头部
List<byte> Header = data.Take(2).ToList();
List<byte> Len = data.Skip(2).Take(2).ToList();
int Len_int = BitConverter.ToInt16(Len.ToArray(), 0);
List<byte> ID = data.Skip(4).Take(4).ToList();
List<byte> CMD = data.Skip(8).Take(1).ToList();
List<byte> Frame = data.Skip(9).Take(2).ToList();
List<byte> Project_Code = data.Skip(11).Take(2).ToList();
// 提取命令类型
byte cmdType_byte = CMD[0];
BLWCommandType cmdtype = (BLWCommandType)cmdType_byte;
string CommandType = cmdtype.ToString();
// 根据命令类型处理
if (cmdType_byte == 0x01)
{
// 处理注册命令
if (source_port == ppp && source_ip.Equals(iii))
{
ReallyDealWith(true, data, dest_ip, dest_port, CommandType, ConstKey.Send_TX);
}
else
{
ReallyDealWith(true, data, source_ip, source_port, CommandType);
}
}
else if (cmdType_byte == 0x02)
{
// 处理心跳包
// ...
}
else
{
// 处理其他命令
// ...
}
}
catch (Exception ex)
{
// 异常处理
}
}
3.3 MQTT 数据发送
功能说明:将分析结果通过 MQTT 协议发送到指定的 MQTT 服务器。
实现逻辑:
- 在
HttpSend.cs中,SendLog和SendLog_2方法接收处理后的数据 - 将数据转换为
MonitorLog对象并序列化为 JSON 字符串 - 通过 MQTT 客户端将 JSON 数据发布到指定的 MQTT 主题
关键代码:
// HttpSend.cs: 发送 MQTT 数据
public static async void SendLog(string xiaodu, string tianmao, string MyCommandType, long hotel_code, int host_id, string roomnumber, string hostnumber, string WWW_IP, int WWW_Port, string lan_ip, int lan_port, string mac, string send_or_receive, string dataHex)
{
try
{
string ti = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
MonitorLog mm = new MonitorLog();
// 设置监控日志对象属性
mm.HotelCode = hotel_code;
mm.HostID = host_id;
mm.HostNumber = hostnumber;
mm.RoomNo = roomnumber;
// ... 其他属性设置
// 序列化为 JSON
string str = Newtonsoft.Json.JsonConvert.SerializeObject(mm);
// 发送到 MQTT 服务器
await Program.mqttClient.PublishStringAsync(debug_log_report_mqtt_topic, str);
}
catch (Exception ex)
{
Console.WriteLine("发送MQTT数据出错:" + ex.Message);
}
}
3.4 MQTT 客户端管理
功能说明:管理 MQTT 客户端连接,包括初始化、连接、重连和订阅主题。
实现逻辑:
- 在
Program.cs中,Start_MqttClient方法初始化 MQTT 客户端 - 设置 MQTT 服务器地址、端口、用户名和密码
- 注册
ApplicationMessageReceivedAsync和DisconnectedAsync事件处理程序 - 连接到 MQTT 服务器并订阅指定主题
关键代码:
// Program.cs: 启动 MQTT 客户端
async public static Task Start_MqttClient()
{
try
{
var mqttFactory = new MqttClientFactory();
// 读取配置
string? ip = ReadConfig.Instance.MQTT_ServerIP;
int? port = ReadConfig.Instance.MQTT_ServerPort;
string? username = ReadConfig.Instance.MQTT_User;
string? pwd = ReadConfig.Instance.MQTT_PassWord;
// 创建客户端 ID
string lid = Guid.NewGuid().ToString("N");
string ID = $"logmonitor_{lid}";
mqttClient = mqttFactory.CreateMqttClient();
// 设置连接选项
var mqttClientOptions = new MqttClientOptionsBuilder()
.WithClientId(ID)
.WithTcpServer(ip, port)
.WithCredentials(username, pwd)
.WithProtocolVersion(MQTTnet.Formatter.MqttProtocolVersion.V500)
.Build();
// 注册事件处理程序
mqttClient.ApplicationMessageReceivedAsync += MqttClient_ApplicationMessageReceivedAsync;
mqttClient.DisconnectedAsync += MqttClient_DisconnectedAsync;
// 连接到 MQTT 服务器
await mqttClient.ConnectAsync(mqttClientOptions, CancellationToken.None);
// 订阅主题
var subscribeOptions = new MqttClientSubscribeOptions();
var topicFilter = new MqttTopicFilter
{
Topic = "blw/logmonitor/delete/report"
};
subscribeOptions.TopicFilters.Add(topicFilter);
await mqttClient.SubscribeAsync(subscribeOptions, CancellationToken.None);
}
catch (Exception ex)
{
Console.WriteLine("Start_MqttClient: " + ex.Message);
}
}
3.5 设备管理与监控
功能说明:管理网络设备,包括设备列表获取、监控启动和停止。
实现逻辑:
- 在
PubRepository.cs中,GetDeviceList方法获取可用的网络设备列表 StartMonitor方法启动指定设备的监控StopMonitor方法停止监控并释放资源
关键代码:
// PubRepository.cs: 启动监控
public static void StartMonitor(int i)
{
PubRepository.log = new LogExecute();
PubRepository.log.Execute(i);
}
// PubRepository.cs: 停止监控
public static void StopMonitor()
{
try
{
PubRepository.liveDevice.StopCapture();
PubRepository.liveDevice.Dispose();
PubRepository.log = null;
}
catch (Exception)
{
// 异常处理
}
}
4. 工作流程
-
程序启动:
- 初始化缓存,从 Redis 获取监控主机列表和端点监控列表
- 启动 MQTT 客户端,连接到 MQTT 服务器
- 启动定时任务,定期更新缓存和发送心跳包
-
设备选择:
- 列出可用的网络设备
- 用户选择要监控的网络设备(当前硬编码为 3)
-
监控开始:
- 启动选定设备的监控
- 设置 UDP 数据包过滤器
- 注册数据包到达事件处理程序
-
数据包处理:
- 当有 UDP 数据包到达时,触发事件处理程序
- 解析数据包,提取源/目标 IP、端口和数据内容
- 根据命令类型进行相应处理
- 提取设备信息,查询房间信息(如果需要)
- 将处理结果通过 MQTT 发送
-
监控维护:
- 定时更新缓存中的监控主机列表和端点监控列表
- 检测 MQTT 连接状态,断开时自动重连
- 定期发送心跳包,保持 MQTT 连接活跃
-
程序结束:
- 停止监控
- 释放资源
5. 配置文件
LogCap 项目使用 app.json 文件存储配置信息,主要包括以下配置项:
| 配置项 | 说明 | 默认值 |
|---|---|---|
| monitor_filter | 网络数据包过滤器 | - |
| monitor_server_ip | 监控服务器 IP | - |
| monitor_server_port | 监控服务器端口 | 3339 |
| MQTT_ServerIP | MQTT 服务器 IP | - |
| MQTT_ServerPort | MQTT 服务器端口 | 1883 |
| MQTT_User | MQTT 用户名 | - |
| MQTT_PWD | MQTT 密码 | - |
| debug_log_report_mqtt_topic | MQTT 发布主题 | - |
| CRICS_URL | HTTP API 基础 URL | - |
6. 技术特点
-
高效的数据包处理:
- 使用异步处理方式,提高数据包处理效率
- 采用内存缓存,减少重复查询和计算
-
稳定的 MQTT 连接:
- 实现 MQTT 断线重连机制
- 定期发送心跳包,保持连接活跃
-
灵活的配置管理:
- 使用 JSON 配置文件,便于修改和管理
- 支持不同环境的配置切换
-
完善的错误处理:
- 捕获并记录异常,确保程序稳定运行
- 提供详细的日志记录,便于问题排查
-
模块化设计:
- 功能模块分离,便于维护和扩展
- 代码结构清晰,易于理解和修改
7. 应用场景
LogCap 项目适用于以下场景:
- 网络设备监控:实时监控网络设备的通信情况,包括设备注册、心跳和状态上报
- 网络故障排查:通过分析网络数据包,快速定位网络故障
- 设备状态管理:跟踪设备的在线状态和通信情况
- 网络流量分析:统计和分析网络流量,优化网络配置
- 安全监控:检测异常网络行为,提高网络安全性
8. 代码优化建议
-
异常处理改进:
- 当前代码中存在多处空异常捕获,建议添加具体的异常处理逻辑,提高代码的可维护性和可调试性
-
配置管理优化:
- 建议使用强类型配置类,替代当前的字符串配置项,减少配置错误的可能性
-
内存管理:
- 对于大量数据包的处理,建议使用对象池或其他内存优化技术,减少内存分配和垃圾回收
-
日志系统:
- 建议使用更完善的日志系统,如 NLog 或 Serilog,提供更详细的日志信息
-
代码结构优化:
- 建议将业务逻辑进一步分离,提高代码的可读性和可测试性
- 考虑使用依赖注入,减少组件之间的耦合
-
性能优化:
- 对于高频数据包的处理,建议使用更高效的数据结构和算法
- 考虑使用多线程或并行处理,提高处理速度
9. 总结
LogCap 是一个功能完善的网络数据包监控和分析工具,通过抓取 UDP 数据包并分析其内容,实现了对网络设备的实时监控和数据采集。该项目使用 C# 和 .NET 框架开发,结合 SharpPcap 和 MQTTnet 等库,实现了高效的数据包处理和传输。
项目的主要优势在于:
- 实时监控网络设备的通信情况
- 高效的数据包处理和分析
- 稳定的 MQTT 数据传输
- 灵活的配置管理
- 模块化的代码结构
LogCap 项目可以作为网络监控系统的核心组件,为网络管理和故障排查提供重要的技术支持。通过进一步优化和扩展,该项目可以应用于更广泛的网络监控场景,为网络运维提供更全面的解决方案。