From 7ec9621901eacd2b9650daef4d6f3b01f9e3c6ac Mon Sep 17 00:00:00 2001 From: TianMaiCheng <746290578@qq.com> Date: Tue, 10 Mar 2026 15:56:53 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=B8=80=E4=BA=9BBUG?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- LogCap/Common/DealWithData.cs | 95 ++-- LogCap/Common/HttpSend.cs | 12 +- .../PublishProfiles/FolderProfile.pubxml.user | 2 +- LogCap_Project_Analysis.md | 404 ++++++++++++++++++ 4 files changed, 470 insertions(+), 43 deletions(-) create mode 100644 LogCap_Project_Analysis.md diff --git a/LogCap/Common/DealWithData.cs b/LogCap/Common/DealWithData.cs index a5f2631..299c7e8 100644 --- a/LogCap/Common/DealWithData.cs +++ b/LogCap/Common/DealWithData.cs @@ -55,6 +55,10 @@ namespace LogCap.Common List MsgData = data.Skip(15).Take(Len_int - 15 - 2).ToList(); List CRC_byte = data.TakeLast(2).ToList(); + if (source_ip.Equals("106.32.130.149")&&source_port==3386) + { + _logger.Error("data:"+Tools.ByteToString(data.ToArray())); + } string Key = string.Format("{0}_{1}_{2}", CacheKey.RoomIP_Port_Prefix, source_ip, source_port); string Dest_Key = string.Format("{0}_{1}_{2}", CacheKey.RoomIP_Port_Prefix, dest_ip, dest_port); @@ -170,39 +174,39 @@ namespace LogCap.Common //设备状态上报 if (cmdType_byte == 0x0E) { - if (MsgData != null && MsgData.Count > 0) + if (MsgData != null && MsgData.Count > 8) { //设备的数量 byte[] couont = MsgData.Skip(7).Take(1).ToArray(); - int Count = couont[0]; - - var MMN = MsgData.Skip(8); - for (int j = 0; j < Count; j++) + if (couont.Length > 0) { - var DeviceData = MMN.Skip(j * 5).Take(5).ToArray(); - if (DeviceData[0] == 0x0A) + int Count = couont[0]; + + var MMN = MsgData.Skip(8); + for (int j = 0; j < Count; j++) { - byte n1 = DeviceData[0]; - byte n2 = DeviceData[1]; + var DeviceData = MMN.Skip(j * 5).Take(5).ToArray(); + if (DeviceData.Length >= 5 && DeviceData[0] == 0x0A) + { + byte n1 = DeviceData[0]; + byte n2 = DeviceData[1]; - byte[] vvv = new byte[] { DeviceData[4] }; + byte[] vvv = new byte[] { DeviceData[4] }; + BitArray bitArray = new BitArray(vvv); + //卡身份 + var qqq1 = bitArray.Cast().Take(1).ToArray(); - BitArray bitArray = new BitArray(vvv); - - - - //卡身份 - var qqq1 = bitArray.Cast().Take(1).ToArray(); - - var qqq2 = bitArray.Cast().Skip(1).Take(3).ToArray(); - - var qqq3 = qqq2.ToArray().Prepend(false).ToArray(); - //节能状态 - byte hhhg1 = Tools.CombineBitsToByte(qqq3[3], qqq3[2], qqq3[1], qqq3[0]); - + var qqq2 = bitArray.Cast().Skip(1).Take(3).ToArray(); + var qqq3 = qqq2.ToArray().Prepend(false).ToArray(); + //节能状态 + if (qqq3.Length >= 4) + { + byte hhhg1 = Tools.CombineBitsToByte(qqq3[3], qqq3[2], qqq3[1], qqq3[0]); + } + } } } } @@ -240,6 +244,10 @@ namespace LogCap.Common { try { + if (data == null || data.Count < 13) + { + return; + } ////系统 ID 的四个字节。固定“T3SA” //List ID = data.Skip(4).Take(4).ToList(); @@ -252,16 +260,19 @@ namespace LogCap.Common //Project_Code List Project_Code = data.Skip(11).Take(2).ToList(); - ushort hotel_code_o = BitConverter.ToUInt16(Project_Code.ToArray(), 0); + if (Project_Code.Count >= 2) + { + ushort hotel_code_o = BitConverter.ToUInt16(Project_Code.ToArray(), 0); - ////MAC - //List IP3 = data.Skip(13).Take(1).ToList(); - //List IP4 = data.Skip(14).Take(1).ToList(); + ////MAC + //List IP3 = data.Skip(13).Take(1).ToList(); + //List IP4 = data.Skip(14).Take(1).ToList(); - long hotel_code = hotel_code_o; - string hostnumber = ""; - string hexdata = Tools.ByteToString(data.ToArray()); - HttpSend.SendLog_2(cmdtype, hotel_code, 0, "", hostnumber, source_ip, source_port, "", 0, "", Send_Or_Receive, hexdata); + long hotel_code = hotel_code_o; + string hostnumber = ""; + string hexdata = Tools.ByteToString(data.ToArray()); + HttpSend.SendLog_2(cmdtype, hotel_code, 0, "", hostnumber, source_ip, source_port, "", 0, "", Send_Or_Receive, hexdata); + } } catch (Exception) { @@ -281,28 +292,34 @@ namespace LogCap.Common ReceiverContext context = new ReceiverContext(data.ToArray()); context.SystemHeader = DecodeSystemHeader(context.Data); + if (!context.SystemHeader.HasValue) + { + return; + } + string Ghostnumber = context.SystemHeader.Value.HostNumber.ToString() ?? ""; if (string.IsNullOrEmpty(Ghostnumber)) { return; } long HHH = 0; - - var abd = context.SystemHeader.HasValue; - if (abd == false) - { - return; - } try { HHH = context.SystemHeader.Value.HostNumber.ToHotelCode(); } catch (Exception) { - var data_error= Tools.ByteToString(data.ToArray()); - Console.WriteLine("ErrorData"+data_error); + var data_error = Tools.ByteToString(data.ToArray()); + Console.WriteLine("ErrorData" + data_error); return; } + //var MAC = BitConverter.ToString(context.Data.Skip(9).Take(2).ToArray()); + + //if (MAC.ToLower().Equals("9CD6")) + //{ + // _logger.Info("MAC:" + MAC); + // _logger.Info("data:" + Tools.ByteToString(data.ToArray())); + //} var list = Program.Cache.Get>(CacheKey.Key); diff --git a/LogCap/Common/HttpSend.cs b/LogCap/Common/HttpSend.cs index a3aaef1..a4bab14 100644 --- a/LogCap/Common/HttpSend.cs +++ b/LogCap/Common/HttpSend.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Configuration; using System.Linq; @@ -63,7 +63,10 @@ namespace LogCap.Common //var payload_data= Encoding.UTF8.GetBytes(str); - await Program.mqttClient.PublishStringAsync(debug_log_report_mqtt_topic, str); + if (Program.mqttClient != null && Program.mqttClient.IsConnected) + { + await Program.mqttClient.PublishStringAsync(debug_log_report_mqtt_topic, str); + } } catch (Exception ex) { @@ -97,7 +100,10 @@ namespace LogCap.Common mm.TiaoMaoCUID = ""; string str = Newtonsoft.Json.JsonConvert.SerializeObject(mm); - await Program.mqttClient.PublishStringAsync(debug_log_report_mqtt_topic_new, str); + if (Program.mqttClient != null && Program.mqttClient.IsConnected) + { + await Program.mqttClient.PublishStringAsync(debug_log_report_mqtt_topic_new, str); + } } catch (Exception ex) { diff --git a/LogCap/Properties/PublishProfiles/FolderProfile.pubxml.user b/LogCap/Properties/PublishProfiles/FolderProfile.pubxml.user index 967e910..48c1409 100644 --- a/LogCap/Properties/PublishProfiles/FolderProfile.pubxml.user +++ b/LogCap/Properties/PublishProfiles/FolderProfile.pubxml.user @@ -4,7 +4,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121. --> - True|2026-01-21T08:04:29.2346921Z||;True|2026-01-08T17:31:34.8778232+08:00||;True|2026-01-08T17:29:38.5339303+08:00||;True|2026-01-08T17:17:34.1517942+08:00||;True|2026-01-08T17:13:33.6164621+08:00||;True|2026-01-08T16:50:29.4216579+08:00||;True|2026-01-08T16:42:32.5476567+08:00||;True|2025-11-18T10:38:51.0970145+08:00||;True|2025-11-18T10:38:36.6590100+08:00||;True|2025-11-18T09:55:20.7541888+08:00||;True|2025-11-18T09:54:09.8014429+08:00||;True|2025-11-18T09:03:03.6239935+08:00||;True|2025-11-12T13:37:44.5193799+08:00||;True|2025-11-04T19:04:11.1977717+08:00||;True|2025-10-15T14:12:11.7503437+08:00||;True|2025-09-29T09:53:03.7995047+08:00||;True|2025-09-29T09:52:00.2305647+08:00||;True|2025-09-29T09:49:50.6101495+08:00||;True|2025-09-29T09:35:55.7152890+08:00||;True|2025-09-29T09:34:28.6196941+08:00||;True|2025-09-29T09:31:27.1029278+08:00||;True|2025-09-29T09:31:20.5804056+08:00||;True|2025-09-29T09:29:27.0993157+08:00||;True|2025-09-29T09:26:09.9458028+08:00||;True|2025-09-11T14:19:22.7215134+08:00||;True|2025-07-21T09:19:25.8321680+08:00||;True|2025-07-18T16:09:34.8867018+08:00||;True|2025-07-18T16:06:18.6358237+08:00||;True|2025-07-18T15:49:28.4034135+08:00||;True|2025-07-18T15:38:30.1452114+08:00||;True|2025-07-18T15:37:55.7831800+08:00||;True|2025-07-18T15:26:49.0230860+08:00||;True|2025-07-18T15:14:11.3917759+08:00||;True|2025-07-18T14:53:35.1351174+08:00||;True|2025-07-18T14:51:40.7222368+08:00||;True|2025-07-18T14:50:19.5264194+08:00||;True|2025-07-18T14:48:37.5000171+08:00||;True|2025-07-18T14:46:06.6645443+08:00||;True|2025-07-18T14:43:35.5161662+08:00||;True|2025-07-18T14:41:32.1953723+08:00||;True|2025-07-18T14:39:41.8990197+08:00||;True|2025-07-18T14:37:59.5226728+08:00||;False|2025-07-18T14:36:34.9869313+08:00||;False|2025-07-18T14:36:28.5844407+08:00||;True|2025-07-18T14:33:19.7559086+08:00||;True|2025-07-18T14:31:58.6399805+08:00||;True|2025-07-18T14:29:41.3500470+08:00||;True|2025-07-18T14:25:09.8903114+08:00||;True|2025-07-18T14:04:10.8844905+08:00||;True|2025-07-18T13:30:11.7855851+08:00||;True|2025-07-18T13:17:27.5926995+08:00||;True|2025-07-16T09:38:37.9415699+08:00||;True|2025-07-16T09:29:01.5138136+08:00||;True|2025-07-16T09:21:08.0981473+08:00||;True|2025-07-15T17:38:31.1667932+08:00||;True|2025-07-15T16:43:05.4527411+08:00||;True|2025-07-07T10:16:09.3877487+08:00||;True|2025-07-07T10:10:49.7560402+08:00||;True|2025-06-17T14:46:41.6347900+08:00||;True|2025-06-17T14:39:33.5356221+08:00||;True|2025-06-17T14:35:00.6059962+08:00||;True|2025-06-16T14:29:42.1186724+08:00||;True|2025-04-10T16:27:27.4571680+08:00||;True|2025-04-10T16:26:52.4704500+08:00||;True|2025-04-10T16:23:44.7512424+08:00||;True|2025-04-10T16:20:38.5807986+08:00||;True|2025-04-10T16:18:39.7753691+08:00||;True|2025-04-10T16:14:06.5114394+08:00||;True|2025-04-09T15:37:02.3941152+08:00||;True|2025-04-09T14:51:04.4433953+08:00||;True|2025-04-09T09:50:05.6074325+08:00||;True|2025-04-08T19:25:32.8536115+08:00||;False|2025-04-08T19:23:51.5364323+08:00||;True|2025-04-08T09:23:44.2543020+08:00||;True|2025-04-08T09:22:54.9082916+08:00||;True|2025-03-31T16:13:42.0797431+08:00||;True|2025-03-31T16:13:15.4339600+08:00||;True|2025-03-31T16:12:35.5470378+08:00||;True|2025-03-31T16:12:06.9833114+08:00||;True|2025-03-31T16:04:47.2437329+08:00||;True|2025-03-31T15:27:09.4504997+08:00||;True|2025-03-14T19:40:25.2983776+08:00||;True|2025-03-10T09:17:51.3361540+08:00||;True|2025-03-10T09:09:10.4750125+08:00||;True|2025-03-08T16:44:19.0185608+08:00||;True|2025-03-08T16:38:26.8544178+08:00||;True|2025-03-07T08:58:41.8621312+08:00||;True|2025-03-07T08:58:23.6999802+08:00||;True|2025-03-05T16:32:51.3089913+08:00||;True|2025-03-05T15:52:19.9963516+08:00||;True|2025-03-05T15:52:02.6859260+08:00||;True|2025-03-04T14:09:36.4338421+08:00||;True|2025-03-04T10:05:44.6777562+08:00||;True|2025-03-04T09:12:49.9348187+08:00||;True|2025-03-03T08:47:09.8416556+08:00||;True|2025-03-03T08:44:56.7823894+08:00||;True|2025-02-21T14:47:27.2104567+08:00||;True|2025-02-21T14:42:30.8494218+08:00||;True|2025-02-21T14:36:24.1989089+08:00||;True|2025-02-21T14:34:10.8466400+08:00||; + True|2026-03-05T06:09:58.2362427Z||;True|2026-03-05T11:58:22.5560787+08:00||;True|2026-03-05T11:52:20.1939003+08:00||;True|2026-03-05T11:50:40.1794133+08:00||;True|2026-03-05T11:38:59.6720357+08:00||;True|2026-03-05T11:35:44.6603884+08:00||;True|2026-03-05T11:35:32.6893445+08:00||;True|2026-03-05T11:32:01.3184104+08:00||;True|2026-03-03T13:19:47.4354530+08:00||;True|2026-01-21T16:04:29.2346921+08:00||;True|2026-01-08T17:31:34.8778232+08:00||;True|2026-01-08T17:29:38.5339303+08:00||;True|2026-01-08T17:17:34.1517942+08:00||;True|2026-01-08T17:13:33.6164621+08:00||;True|2026-01-08T16:50:29.4216579+08:00||;True|2026-01-08T16:42:32.5476567+08:00||;True|2025-11-18T10:38:51.0970145+08:00||;True|2025-11-18T10:38:36.6590100+08:00||;True|2025-11-18T09:55:20.7541888+08:00||;True|2025-11-18T09:54:09.8014429+08:00||;True|2025-11-18T09:03:03.6239935+08:00||;True|2025-11-12T13:37:44.5193799+08:00||;True|2025-11-04T19:04:11.1977717+08:00||;True|2025-10-15T14:12:11.7503437+08:00||;True|2025-09-29T09:53:03.7995047+08:00||;True|2025-09-29T09:52:00.2305647+08:00||;True|2025-09-29T09:49:50.6101495+08:00||;True|2025-09-29T09:35:55.7152890+08:00||;True|2025-09-29T09:34:28.6196941+08:00||;True|2025-09-29T09:31:27.1029278+08:00||;True|2025-09-29T09:31:20.5804056+08:00||;True|2025-09-29T09:29:27.0993157+08:00||;True|2025-09-29T09:26:09.9458028+08:00||;True|2025-09-11T14:19:22.7215134+08:00||;True|2025-07-21T09:19:25.8321680+08:00||;True|2025-07-18T16:09:34.8867018+08:00||;True|2025-07-18T16:06:18.6358237+08:00||;True|2025-07-18T15:49:28.4034135+08:00||;True|2025-07-18T15:38:30.1452114+08:00||;True|2025-07-18T15:37:55.7831800+08:00||;True|2025-07-18T15:26:49.0230860+08:00||;True|2025-07-18T15:14:11.3917759+08:00||;True|2025-07-18T14:53:35.1351174+08:00||;True|2025-07-18T14:51:40.7222368+08:00||;True|2025-07-18T14:50:19.5264194+08:00||;True|2025-07-18T14:48:37.5000171+08:00||;True|2025-07-18T14:46:06.6645443+08:00||;True|2025-07-18T14:43:35.5161662+08:00||;True|2025-07-18T14:41:32.1953723+08:00||;True|2025-07-18T14:39:41.8990197+08:00||;True|2025-07-18T14:37:59.5226728+08:00||;False|2025-07-18T14:36:34.9869313+08:00||;False|2025-07-18T14:36:28.5844407+08:00||;True|2025-07-18T14:33:19.7559086+08:00||;True|2025-07-18T14:31:58.6399805+08:00||;True|2025-07-18T14:29:41.3500470+08:00||;True|2025-07-18T14:25:09.8903114+08:00||;True|2025-07-18T14:04:10.8844905+08:00||;True|2025-07-18T13:30:11.7855851+08:00||;True|2025-07-18T13:17:27.5926995+08:00||;True|2025-07-16T09:38:37.9415699+08:00||;True|2025-07-16T09:29:01.5138136+08:00||;True|2025-07-16T09:21:08.0981473+08:00||;True|2025-07-15T17:38:31.1667932+08:00||;True|2025-07-15T16:43:05.4527411+08:00||;True|2025-07-07T10:16:09.3877487+08:00||;True|2025-07-07T10:10:49.7560402+08:00||;True|2025-06-17T14:46:41.6347900+08:00||;True|2025-06-17T14:39:33.5356221+08:00||;True|2025-06-17T14:35:00.6059962+08:00||;True|2025-06-16T14:29:42.1186724+08:00||;True|2025-04-10T16:27:27.4571680+08:00||;True|2025-04-10T16:26:52.4704500+08:00||;True|2025-04-10T16:23:44.7512424+08:00||;True|2025-04-10T16:20:38.5807986+08:00||;True|2025-04-10T16:18:39.7753691+08:00||;True|2025-04-10T16:14:06.5114394+08:00||;True|2025-04-09T15:37:02.3941152+08:00||;True|2025-04-09T14:51:04.4433953+08:00||;True|2025-04-09T09:50:05.6074325+08:00||;True|2025-04-08T19:25:32.8536115+08:00||;False|2025-04-08T19:23:51.5364323+08:00||;True|2025-04-08T09:23:44.2543020+08:00||;True|2025-04-08T09:22:54.9082916+08:00||;True|2025-03-31T16:13:42.0797431+08:00||;True|2025-03-31T16:13:15.4339600+08:00||;True|2025-03-31T16:12:35.5470378+08:00||;True|2025-03-31T16:12:06.9833114+08:00||;True|2025-03-31T16:04:47.2437329+08:00||;True|2025-03-31T15:27:09.4504997+08:00||;True|2025-03-14T19:40:25.2983776+08:00||;True|2025-03-10T09:17:51.3361540+08:00||;True|2025-03-10T09:09:10.4750125+08:00||;True|2025-03-08T16:44:19.0185608+08:00||;True|2025-03-08T16:38:26.8544178+08:00||;True|2025-03-07T08:58:41.8621312+08:00||;True|2025-03-07T08:58:23.6999802+08:00||;True|2025-03-05T16:32:51.3089913+08:00||;True|2025-03-05T15:52:19.9963516+08:00||;True|2025-03-05T15:52:02.6859260+08:00||; \ No newline at end of file diff --git a/LogCap_Project_Analysis.md b/LogCap_Project_Analysis.md new file mode 100644 index 0000000..7490711 --- /dev/null +++ b/LogCap_Project_Analysis.md @@ -0,0 +1,404 @@ +# 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 项目可以作为网络监控系统的核心组件,为网络管理和故障排查提供重要的技术支持。通过进一步优化和扩展,该项目可以应用于更广泛的网络监控场景,为网络运维提供更全面的解决方案。 \ No newline at end of file