# 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 数据包,并对数据包进行解析和分析。 **实现逻辑**: 1. 在 `LogExecute.cs` 中,通过 `Execute` 方法初始化网络设备并设置过滤器 2. 注册 `device_OnPacketArrival` 事件处理程序,当有数据包到达时触发 3. 在事件处理程序中,解析数据包,提取源/目标 IP、端口和数据内容 4. 调用 `DealWithData.HandleData` 方法处理数据包内容 **关键代码**: ```csharp // 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 ddd = new Tuple(Data, SourceAddress, SourcePort, DestinationAddress, DestinationPort); Task.Factory.StartNew((State) => { var tf = State as Tuple; DealWithData.HandleData(tf.Item1.ToList(), tf.Item2.ToString(), tf.Item3, tf.Item4.ToString(), tf.Item5); }, ddd); } catch (Exception ex) { // 异常处理 } } ``` ### 3.2 数据包处理与解析 **功能说明**:解析 UDP 数据包内容,提取设备信息、命令类型等关键数据,并根据数据包类型进行相应处理。 **实现逻辑**: 1. 在 `DealWithData.cs` 中,`HandleData` 方法接收数据包内容和网络信息 2. 解析数据包头部,提取命令类型、项目代码等信息 3. 根据命令类型(注册、心跳、设备状态等)进行不同处理 4. 调用 `ReallyDealWith` 方法处理具体业务逻辑 **关键代码**: ```csharp // DealWithData.cs: 处理数据包 public static void HandleData(List data, string source_ip, ushort source_port, string dest_ip, ushort dest_port) { try { // 解析数据包头部 List Header = data.Take(2).ToList(); List Len = data.Skip(2).Take(2).ToList(); int Len_int = BitConverter.ToInt16(Len.ToArray(), 0); List ID = data.Skip(4).Take(4).ToList(); List CMD = data.Skip(8).Take(1).ToList(); List Frame = data.Skip(9).Take(2).ToList(); List 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 服务器。 **实现逻辑**: 1. 在 `HttpSend.cs` 中,`SendLog` 和 `SendLog_2` 方法接收处理后的数据 2. 将数据转换为 `MonitorLog` 对象并序列化为 JSON 字符串 3. 通过 MQTT 客户端将 JSON 数据发布到指定的 MQTT 主题 **关键代码**: ```csharp // 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 客户端连接,包括初始化、连接、重连和订阅主题。 **实现逻辑**: 1. 在 `Program.cs` 中,`Start_MqttClient` 方法初始化 MQTT 客户端 2. 设置 MQTT 服务器地址、端口、用户名和密码 3. 注册 `ApplicationMessageReceivedAsync` 和 `DisconnectedAsync` 事件处理程序 4. 连接到 MQTT 服务器并订阅指定主题 **关键代码**: ```csharp // 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 设备管理与监控 **功能说明**:管理网络设备,包括设备列表获取、监控启动和停止。 **实现逻辑**: 1. 在 `PubRepository.cs` 中,`GetDeviceList` 方法获取可用的网络设备列表 2. `StartMonitor` 方法启动指定设备的监控 3. `StopMonitor` 方法停止监控并释放资源 **关键代码**: ```csharp // 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. 工作流程 1. **程序启动**: - 初始化缓存,从 Redis 获取监控主机列表和端点监控列表 - 启动 MQTT 客户端,连接到 MQTT 服务器 - 启动定时任务,定期更新缓存和发送心跳包 2. **设备选择**: - 列出可用的网络设备 - 用户选择要监控的网络设备(当前硬编码为 3) 3. **监控开始**: - 启动选定设备的监控 - 设置 UDP 数据包过滤器 - 注册数据包到达事件处理程序 4. **数据包处理**: - 当有 UDP 数据包到达时,触发事件处理程序 - 解析数据包,提取源/目标 IP、端口和数据内容 - 根据命令类型进行相应处理 - 提取设备信息,查询房间信息(如果需要) - 将处理结果通过 MQTT 发送 5. **监控维护**: - 定时更新缓存中的监控主机列表和端点监控列表 - 检测 MQTT 连接状态,断开时自动重连 - 定期发送心跳包,保持 MQTT 连接活跃 6. **程序结束**: - 停止监控 - 释放资源 ## 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. 技术特点 1. **高效的数据包处理**: - 使用异步处理方式,提高数据包处理效率 - 采用内存缓存,减少重复查询和计算 2. **稳定的 MQTT 连接**: - 实现 MQTT 断线重连机制 - 定期发送心跳包,保持连接活跃 3. **灵活的配置管理**: - 使用 JSON 配置文件,便于修改和管理 - 支持不同环境的配置切换 4. **完善的错误处理**: - 捕获并记录异常,确保程序稳定运行 - 提供详细的日志记录,便于问题排查 5. **模块化设计**: - 功能模块分离,便于维护和扩展 - 代码结构清晰,易于理解和修改 ## 7. 应用场景 LogCap 项目适用于以下场景: 1. **网络设备监控**:实时监控网络设备的通信情况,包括设备注册、心跳和状态上报 2. **网络故障排查**:通过分析网络数据包,快速定位网络故障 3. **设备状态管理**:跟踪设备的在线状态和通信情况 4. **网络流量分析**:统计和分析网络流量,优化网络配置 5. **安全监控**:检测异常网络行为,提高网络安全性 ## 8. 代码优化建议 1. **异常处理改进**: - 当前代码中存在多处空异常捕获,建议添加具体的异常处理逻辑,提高代码的可维护性和可调试性 2. **配置管理优化**: - 建议使用强类型配置类,替代当前的字符串配置项,减少配置错误的可能性 3. **内存管理**: - 对于大量数据包的处理,建议使用对象池或其他内存优化技术,减少内存分配和垃圾回收 4. **日志系统**: - 建议使用更完善的日志系统,如 NLog 或 Serilog,提供更详细的日志信息 5. **代码结构优化**: - 建议将业务逻辑进一步分离,提高代码的可读性和可测试性 - 考虑使用依赖注入,减少组件之间的耦合 6. **性能优化**: - 对于高频数据包的处理,建议使用更高效的数据结构和算法 - 考虑使用多线程或并行处理,提高处理速度 ## 9. 总结 LogCap 是一个功能完善的网络数据包监控和分析工具,通过抓取 UDP 数据包并分析其内容,实现了对网络设备的实时监控和数据采集。该项目使用 C# 和 .NET 框架开发,结合 SharpPcap 和 MQTTnet 等库,实现了高效的数据包处理和传输。 项目的主要优势在于: - 实时监控网络设备的通信情况 - 高效的数据包处理和分析 - 稳定的 MQTT 数据传输 - 灵活的配置管理 - 模块化的代码结构 LogCap 项目可以作为网络监控系统的核心组件,为网络管理和故障排查提供重要的技术支持。通过进一步优化和扩展,该项目可以应用于更广泛的网络监控场景,为网络运维提供更全面的解决方案。