TcpServerFrame.cs 75 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842
  1. using SWRIS.Enums;
  2. using SWRIS.Events;
  3. using SWRIS.Extensions;
  4. using SWRIS.Models;
  5. using SWRIS.Models.Data;
  6. using System;
  7. using System.Collections.Concurrent;
  8. using System.Collections.Generic;
  9. using System.IO;
  10. using System.Linq;
  11. using System.Net;
  12. using System.Net.Sockets;
  13. using System.Reflection;
  14. using System.Security.Cryptography;
  15. using System.Text;
  16. using System.Threading;
  17. using System.Threading.Tasks;
  18. namespace SWRIS.Core
  19. {
  20. public class TcpServerFrame : IDisposable
  21. {
  22. // 定义事件
  23. public event EventHandler<ClientConnectedEventArgs> ClientConnected;
  24. public event EventHandler<ClientDisconnectedEventArgs> ClientDisconnected;
  25. public event EventHandler<LiveStreamReceivedEventArgs> LiveStreamReceived;
  26. public event EventHandler<AlarmDataReceivedEventArgs> AlarmDataReceived;
  27. public event EventHandler<FaultDataReceivedEventArgs> FaultDataReceived;
  28. public event EventHandler<DetectionDataReceivedEventArgs> DetectionDataReceived;
  29. public event EventHandler<RealTimeDataReceivedEventArgs> RealTimeDataReceived;
  30. public event EventHandler<DetectionRawDataReceivedEventArgs> DetectionRawDataReceived;
  31. public event EventHandler<ResetSystemDataReceivedEventArgs> ResetSystemDataReceived;
  32. public event EventHandler<SetAbsolutePositionDataReceivedEventArgs> SetAbsolutePositionDataReceived;
  33. public event EventHandler<DetectionRawDataResultReceivedEventArgs> DetectionRawDataResultReceived;
  34. public event EventHandler<DetectionStatusResultReceivedEventArgs> DetectionStatusResultReceived;
  35. public event EventHandler<UpgradedResultReceivedEventArgs> UpgradedRequestResultReceived;
  36. public event EventHandler<ClockResultReceivedEventArgs> ClockResultReceived;
  37. public event EventHandler<EncoderDirectionResultReceivedEventArgs> EncoderDirectionResultReceived;
  38. public event EventHandler<HeartbeatReceviedEventArgs> HeartbeatReceived;
  39. public event EventHandler<DebugMessageReceivedEventArgs> DebugMessageReceived;
  40. private Socket _listener;
  41. private bool _isRunning;
  42. private readonly string _ipAddress;
  43. private readonly int _port;
  44. private readonly ByteTransform _byteTransform;
  45. private const string PASSWORD = "WNDTM4";
  46. private static ConcurrentDictionary<string, ClientState> _connectedClients;
  47. private CancellationTokenSource ctsToken = new CancellationTokenSource();
  48. public TcpServerFrame(string ipAddress, int port)
  49. {
  50. _ipAddress = ipAddress;
  51. _port = port;
  52. _byteTransform = new ByteTransform(DataFormat.DCBA);
  53. _connectedClients = new ConcurrentDictionary<string, ClientState>();
  54. }
  55. public void Start()
  56. {
  57. _isRunning = true;
  58. _listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  59. try
  60. {
  61. // 使用指定的IP地址和端口
  62. IPAddress ipAddress = IPAddress.Parse(_ipAddress);
  63. _listener.Bind(new IPEndPoint(ipAddress, _port));
  64. _listener.Listen(10);
  65. // 启动心跳检测线程
  66. StartHeartbeatCheck();
  67. // 开始接受客户端连接(异步)
  68. _listener.BeginAccept(OnClientConnected, null);
  69. DebugMessageReceived?.Invoke(this, new DebugMessageReceivedEventArgs($"服务已在 {_ipAddress}:{_port} 上启动"));
  70. }
  71. catch (SocketException ex)
  72. {
  73. LogHelper.Error($"启动服务时发生错误: {ex.Message}");
  74. if (ex.SocketErrorCode == SocketError.AddressAlreadyInUse)
  75. {
  76. LogHelper.Error("端口已被占用,请更换端口或关闭占用该端口的程序", ex);
  77. }
  78. else if (ex.SocketErrorCode == SocketError.AddressNotAvailable)
  79. {
  80. LogHelper.Error($"IP地址 {_ipAddress} 不可用,请检查网络配置", ex);
  81. }
  82. }
  83. catch (Exception ex)
  84. {
  85. LogHelper.Error($"TCP服务启动时发生未知错误: {ex.Message}", ex);
  86. }
  87. }
  88. public void Stop()
  89. {
  90. _isRunning = false;
  91. // 取消心跳检测任务
  92. ctsToken?.Cancel();
  93. ctsToken?.Dispose();
  94. ctsToken = null;
  95. // 关闭所有客户端连接
  96. foreach (var client in _connectedClients.Values)
  97. {
  98. SafeCloseClient(client);
  99. }
  100. _connectedClients.Clear();
  101. // 关闭监听器
  102. if (_listener != null)
  103. {
  104. try
  105. {
  106. _listener.Close();
  107. }
  108. catch (SocketException) { }
  109. catch (ObjectDisposedException) { }
  110. _listener = null;
  111. }
  112. }
  113. private void OnClientConnected(IAsyncResult ar)
  114. {
  115. if (!_isRunning)
  116. return;
  117. try
  118. {
  119. Socket clientSocket = _listener.EndAccept(ar);
  120. string ipAddress = (clientSocket.RemoteEndPoint as IPEndPoint)?.Address?.ToString();
  121. var equipmentData = App.Config.Equipments.FirstOrDefault(c => c.IpAddress == ipAddress);
  122. if (equipmentData != null)
  123. {
  124. ClientState client = new ClientState(clientSocket, ipAddress, equipmentData.SerialNo);
  125. // 添加到连接列表
  126. _connectedClients.TryAdd(client.IpAddress, client);
  127. // 开始异步接收数据
  128. clientSocket.BeginReceive(client.Buffer, 0, client.Buffer.Length, SocketFlags.None, OnDataReceived, client);
  129. // 触发客户端连接事件
  130. ClientConnected?.Invoke(this, new ClientConnectedEventArgs(clientSocket, ipAddress));
  131. }
  132. // 继续接受新连接
  133. _listener.BeginAccept(OnClientConnected, null);
  134. }
  135. catch (Exception ex)
  136. {
  137. LogHelper.Error($"Error accepting client: {ex.Message}", ex);
  138. }
  139. }
  140. private void StartHeartbeatCheck()
  141. {
  142. ThreadPool.QueueUserWorkItem(async state =>
  143. {
  144. var token = (CancellationTokenSource)state;
  145. while (_isRunning && !token.IsCancellationRequested)
  146. {
  147. try
  148. {
  149. await Task.Delay(TimeSpan.FromSeconds(5), token.Token);
  150. foreach (var client in _connectedClients.ToArray())
  151. {
  152. if ((DateTime.UtcNow - client.Value.LastActiveTime).TotalSeconds > 15)
  153. {
  154. SafeCloseClient(client.Value);
  155. DebugMessageReceived?.Invoke(this,
  156. new DebugMessageReceivedEventArgs($"心跳超时,强制断开", ipAddress: client.Value.IpAddress));
  157. }
  158. }
  159. }
  160. catch (TaskCanceledException)
  161. {
  162. // 正常取消,退出循环
  163. break;
  164. }
  165. catch (Exception ex)
  166. {
  167. LogHelper.Error($"心跳检测异常: {ex.Message}", ex);
  168. }
  169. }
  170. }, ctsToken);
  171. }
  172. [Obfuscation(Feature = "virtualization", Exclude = false)]
  173. private async void OnDataReceived(IAsyncResult ar)
  174. {
  175. var state = (ClientState)ar.AsyncState;
  176. if (state == null || state.ClientSocket == null || !state.ClientSocket.Connected)
  177. {
  178. return;
  179. }
  180. try
  181. {
  182. int bytesRead = state.ClientSocket.EndReceive(ar);
  183. if (bytesRead > 0)
  184. {
  185. // 将接收到的数据添加到缓冲区
  186. state.ReceiveBuffer.Write(state.Buffer, 0, bytesRead);
  187. // 处理缓冲区中的所有数据包
  188. while (state.ReceiveBuffer.Length > 0)
  189. {
  190. byte packetType = state.ReceiveBuffer.PeekByte();
  191. if (packetType == 0xC0) // 心跳包
  192. {
  193. ProcessHeartbeatPacket(state);
  194. }
  195. else if (packetType == 0x30) // 数据包
  196. {
  197. bool processed = await ProcessDataPacket(state);
  198. if (!processed) break; // 数据包不完整,等待更多数据
  199. }
  200. else
  201. {
  202. // 未知包类型,跳过1字节继续检查
  203. DebugMessageReceived?.Invoke(this,
  204. new DebugMessageReceivedEventArgs($"未知包类型: 0x{packetType:X2}", state.IpAddress));
  205. state.ReceiveBuffer.Remove(1);
  206. }
  207. }
  208. // 继续接收数据
  209. if (state.ClientSocket != null)
  210. {
  211. Array.Clear(state.Buffer, 0, state.Buffer.Length);
  212. state.ClientSocket.BeginReceive(state.Buffer, 0, state.Buffer.Length,
  213. SocketFlags.None, OnDataReceived, state);
  214. }
  215. }
  216. else
  217. {
  218. // 客户端断开连接
  219. DebugMessageReceived?.Invoke(this,
  220. new DebugMessageReceivedEventArgs((bytesRead == 0 ? "设备主动断开连接" : "连接异常或错误") + $"({bytesRead})", state.IpAddress));
  221. SafeCloseClient(state);
  222. }
  223. }
  224. catch (SocketException sex)
  225. {
  226. HandleSocketException(sex, state);
  227. }
  228. catch (Exception ex)
  229. {
  230. var message = $"接收数据时错误: {ex.Message}";
  231. LogHelper.Error(message, ex);
  232. SafeCloseClient(state);
  233. }
  234. }
  235. private void HandleSocketException(SocketException sex, ClientState client)
  236. {
  237. string message;
  238. switch (sex.SocketErrorCode)
  239. {
  240. case SocketError.ConnectionReset:
  241. message = "设备强制断开连接 (Connection Reset)";
  242. break;
  243. case SocketError.OperationAborted:
  244. message = "操作被中止";
  245. break;
  246. case SocketError.ConnectionAborted:
  247. message = "连接被中止";
  248. break;
  249. case SocketError.TimedOut:
  250. message = "连接超时";
  251. break;
  252. case SocketError.Shutdown:
  253. message = "连接已关闭";
  254. break;
  255. case SocketError.NetworkReset:
  256. message = "网络连接被重置";
  257. break;
  258. case SocketError.HostUnreachable:
  259. message = "主机不可达";
  260. break;
  261. default:
  262. message = $"Socket错误: {sex.SocketErrorCode} - {sex.Message}";
  263. break;
  264. }
  265. DebugMessageReceived?.Invoke(this,
  266. new DebugMessageReceivedEventArgs(message, client.IpAddress));
  267. LogHelper.Error(message, sex);
  268. SafeCloseClient(client);
  269. }
  270. private void ProcessHeartbeatPacket(ClientState client)
  271. {
  272. // 心跳包固定长度为2字节: 0xC0 + 0x00
  273. if (client.ReceiveBuffer.Length < 2)
  274. return; // 等待更多数据
  275. byte[] heartBeatData = new byte[2];
  276. client.ReceiveBuffer.Read(heartBeatData, 0, 2);
  277. client.LastActiveTime = DateTime.UtcNow;
  278. RespondHeartbeat(heartBeatData, client.IpAddress, client.ClientSocket);
  279. HeartbeatReceived?.Invoke(this, new HeartbeatReceviedEventArgs(client.IpAddress));
  280. }
  281. private async Task<bool> ProcessDataPacket(ClientState client)
  282. {
  283. // 检查是否有足够的数据读取长度信息
  284. if (client.ReceiveBuffer.Length < 5) // 至少需要包类型 + 最小长度信息
  285. return false;
  286. // 窥探前10个字节来解析长度
  287. byte[] peekData = new byte[Math.Min(client.ReceiveBuffer.Length, 10)];
  288. int peeked = client.ReceiveBuffer.Peek(peekData, 0, peekData.Length);
  289. // 解析剩余长度
  290. (int byteLength, int remainingLength) = GetRemainingLength(peekData);
  291. if (byteLength == 0 || remainingLength == 0)
  292. {
  293. // 长度解析失败,可能是数据损坏,跳过1字节
  294. client.ReceiveBuffer.Remove(1);
  295. return true;
  296. }
  297. // 计算完整包长度
  298. int totalPacketLength = 1 + byteLength + remainingLength;
  299. // 检查是否收到完整包
  300. if (client.ReceiveBuffer.Length < totalPacketLength)
  301. return false;
  302. // 读取完整数据包
  303. byte[] packetData = new byte[totalPacketLength];
  304. client.ReceiveBuffer.Read(packetData, 0, totalPacketLength);
  305. // 提取事件类型和有效载荷
  306. int payloadStart = 1 + byteLength;
  307. if (payloadStart >= packetData.Length)
  308. {
  309. DebugMessageReceived?.Invoke(this,
  310. new DebugMessageReceivedEventArgs($"数据异常", client.IpAddress));
  311. return true;
  312. }
  313. byte eventType = packetData[payloadStart];
  314. byte[] payload = new byte[remainingLength];
  315. Buffer.BlockCopy(packetData, payloadStart, payload, 0, remainingLength);
  316. // 处理数据包
  317. await ProcessEventByType(eventType, payload, client);
  318. return true;
  319. }
  320. /// <summary>
  321. /// 根据事件类型处理数据
  322. /// </summary>
  323. /// <param name="eventType"></param>
  324. /// <param name="payload"></param>
  325. /// <param name="client"></param>
  326. /// <returns></returns>
  327. [Obfuscation(Feature = "virtualization", Exclude = false)]
  328. private async Task ProcessEventByType(byte eventType, byte[] payload, ClientState client)
  329. {
  330. switch (eventType)
  331. {
  332. case 0x01:
  333. await ProcessSyncParameters(payload, client);
  334. break;
  335. case 0x06:
  336. await ProcessDetectionStatus(payload, client);
  337. break;
  338. case 0x07:
  339. await ProcessFaultData(payload, client);
  340. break;
  341. case 0x08:
  342. await ProcessAlarmData(payload, client);
  343. break;
  344. case 0x09:
  345. await ProcessDetectionData(payload, client);
  346. break;
  347. case 0x10:
  348. await ProcessClockData(payload, client);
  349. break;
  350. case 0x11:
  351. await ProcessUpgradedData(payload, client);
  352. break;
  353. case 0x12:
  354. await ProcessEncoderDirectionData(payload, client);
  355. break;
  356. case 0x13:
  357. await ProcessTwistFactorData(payload, client);
  358. break;
  359. case 0x0A:
  360. await ProcessOpenOrClosedRealtimeData(payload, client);
  361. break;
  362. case 0x0B:
  363. await ProcessRealTimeData(payload, client);
  364. break;
  365. case 0x0D:
  366. await ProcessLiveStreamData(payload, client);
  367. break;
  368. case 0x0C:
  369. await ProcessTurnLiveStreamData(payload, client);
  370. break;
  371. case 0x0E:
  372. await ProcessDetectionRawResultData(payload, client);
  373. break;
  374. case 0x0F:
  375. await ProcessDetectionRawData(payload, client);
  376. break;
  377. case 0x14:
  378. await ProcessSystemResetData(payload, client);
  379. break;
  380. case 0x15:
  381. await ProcessSetAbsolutePositionData(payload, client);
  382. break;
  383. case 0x16:
  384. await ProcessSerialNoData(payload, client);
  385. break;
  386. }
  387. }
  388. /// <summary>
  389. /// 设置实时位置
  390. /// </summary>
  391. /// <param name="buffer"></param>
  392. /// <param name="client"></param>
  393. /// <returns></returns>
  394. private async Task ProcessSetAbsolutePositionData(byte[] buffer, ClientState client)
  395. {
  396. var resetSystemData = ReceiveSetAbsolutePositionData(buffer);
  397. if (resetSystemData != null)
  398. {
  399. // 设置当前实时位置应答
  400. SetAbsolutePositionDataReceived?.Invoke(this,
  401. new SetAbsolutePositionDataReceivedEventArgs(client.IpAddress, resetSystemData));
  402. }
  403. await Task.CompletedTask;
  404. }
  405. /// <summary>
  406. /// 主板复位
  407. /// </summary>
  408. /// <param name="buffer"></param>
  409. /// <param name="client"></param>
  410. /// <returns></returns>
  411. private async Task ProcessSystemResetData(byte[] buffer, ClientState client)
  412. {
  413. var resetSystemData = ReceiveResetSystemData(buffer);
  414. if (resetSystemData != null)
  415. {
  416. // 主板复位结果
  417. ResetSystemDataReceived?.Invoke(this,
  418. new ResetSystemDataReceivedEventArgs(client.IpAddress, resetSystemData));
  419. }
  420. await Task.CompletedTask;
  421. }
  422. private async Task ProcessDetectionRawData(byte[] buffer, ClientState client)
  423. {
  424. await Task.Run(() =>
  425. {
  426. var detectionRawData = ReceiveDetectionRawData(buffer);
  427. if (detectionRawData != null)
  428. {
  429. // 处理检测原始数据
  430. DetectionRawDataReceived?.Invoke(this,
  431. new DetectionRawDataReceivedEventArgs(client.IpAddress, detectionRawData));
  432. }
  433. });
  434. await Task.CompletedTask;
  435. }
  436. private async Task ProcessDetectionRawResultData(byte[] buffer, ClientState client)
  437. {
  438. await Task.Run(() =>
  439. {
  440. var detectionRawResultData = ReceiveDetectionRawResultData(buffer);
  441. if (detectionRawResultData != null)
  442. {
  443. DetectionRawDataResultReceived?.Invoke(this,
  444. new DetectionRawDataResultReceivedEventArgs(client.IpAddress, detectionRawResultData));
  445. }
  446. });
  447. await Task.CompletedTask;
  448. }
  449. private async Task ProcessTurnLiveStreamData(byte[] buffer, ClientState client)
  450. {
  451. var liveStreamStatus = ReceiveTurnLiveStreamData(buffer);
  452. if (liveStreamStatus > 0)
  453. {
  454. // 开启/关闭结果,0=成功,>0=失败-原因码
  455. LogHelper.Error($"开启/关闭实时流数据失败,原因码:{liveStreamStatus}");
  456. }
  457. await Task.CompletedTask;
  458. }
  459. private async Task ProcessLiveStreamData(byte[] buffer, ClientState client)
  460. {
  461. await Task.Run(() =>
  462. {
  463. var liveStreamData = ReceiveLiveStreamDataModel(buffer);
  464. if (liveStreamData != null && liveStreamData.Data.Any())
  465. {
  466. // 触发事件
  467. LiveStreamReceived?.Invoke(this,
  468. new LiveStreamReceivedEventArgs(client.IpAddress, liveStreamData));
  469. }
  470. });
  471. await Task.CompletedTask;
  472. }
  473. private async Task ProcessRealTimeData(byte[] buffer, ClientState client)
  474. {
  475. await Task.Run(() =>
  476. {
  477. var realTimeData = ReceiveRealTimeData(buffer);
  478. if (realTimeData != null)
  479. {
  480. // 触发实时数据接收事件
  481. RealTimeDataReceived?.Invoke(this,
  482. new RealTimeDataReceivedEventArgs(client.IpAddress, realTimeData));
  483. }
  484. });
  485. await Task.CompletedTask;
  486. }
  487. private async Task ProcessOpenOrClosedRealtimeData(byte[] buffer, ClientState client)
  488. {
  489. var openOrClosed = ReceiveOpenOrClosedRealtimeData(buffer);
  490. if (openOrClosed > 0)
  491. {
  492. LogHelper.Error("开启或关闭实时数据失败,原因码:" + openOrClosed);
  493. }
  494. await Task.CompletedTask;
  495. }
  496. private async Task ProcessTwistFactorData(byte[] buffer, ClientState client)
  497. {
  498. var twistFactorData = ReceiveTwistFactorData(buffer);
  499. if (twistFactorData != null)
  500. {
  501. var equipmentData = App.Config.Equipments.FirstOrDefault(c => c.IpAddress == client.IpAddress);
  502. if (equipmentData != null && equipmentData.Parameter != null)
  503. {
  504. // 处理判伤捻距系数数据
  505. equipmentData.Parameter.TwistFactor = twistFactorData.TwistFactor;
  506. }
  507. }
  508. await Task.CompletedTask;
  509. }
  510. private async Task ProcessEncoderDirectionData(byte[] buffer, ClientState client)
  511. {
  512. var encoderDirection = ReceiveEncoderDirectionData(buffer);
  513. if (encoderDirection != null)
  514. {
  515. var equipmentData = App.Config.Equipments.FirstOrDefault(c => c.IpAddress == client.IpAddress);
  516. if (equipmentData != null && equipmentData.Parameter != null)
  517. {
  518. // 处理编码器方向数据
  519. equipmentData.Parameter.EncoderDirection = encoderDirection.Direction;
  520. // 编码器方向结果返回事件
  521. EncoderDirectionResultReceived?.Invoke(this,
  522. new EncoderDirectionResultReceivedEventArgs(client.IpAddress, encoderDirection.Direction));
  523. }
  524. }
  525. await Task.CompletedTask;
  526. }
  527. private async Task ProcessClockData(byte[] buffer, ClientState client)
  528. {
  529. var clockData = ReceiveClockData(buffer);
  530. if (clockData != null)
  531. {
  532. ClockResultReceived?.Invoke(this,
  533. new ClockResultReceivedEventArgs(client.IpAddress, clockData.Time));
  534. }
  535. await Task.CompletedTask;
  536. }
  537. private async Task ProcessDetectionData(byte[] buffer, ClientState client)
  538. {
  539. var detectionData = ReceiveDetectionData(buffer);
  540. if (detectionData != null)
  541. {
  542. // 回复检测结果确认
  543. if (SendDetectionConfirm(detectionData.StartTime, detectionData.EndTime, client.SerialNo, client.ClientSocket))
  544. {
  545. if (detectionData.DamageCount <= 0)
  546. {
  547. DebugMessageReceived?.Invoke(this, new DebugMessageReceivedEventArgs($"检测结果未发现损伤,本次结果不记录",
  548. ipAddress: client.IpAddress,
  549. serialNo: client.SerialNo));
  550. }
  551. else
  552. {
  553. // 发送获取原始数据请求
  554. SendGetDetectionRawData(client.SerialNo, client.ClientSocket);
  555. // 处理检测数据
  556. DetectionDataReceived?.Invoke(this,
  557. new DetectionDataReceivedEventArgs(client.IpAddress, detectionData));
  558. }
  559. }
  560. }
  561. await Task.CompletedTask;
  562. }
  563. private async Task ProcessFaultData(byte[] buffer, ClientState client)
  564. {
  565. var faultData = ReceiveFaultData(buffer);
  566. if (faultData != null)
  567. {
  568. var equipmentData = App.DataCenter.Equipments.FirstOrDefault(c => c.IpAddress == client.IpAddress);
  569. if (equipmentData != null)
  570. {
  571. equipmentData.InUseSensor = faultData.WorkingSensors;
  572. }
  573. // 处理故障数据
  574. FaultDataReceived?.Invoke(this, new FaultDataReceivedEventArgs(client.IpAddress, faultData));
  575. }
  576. await Task.CompletedTask;
  577. }
  578. private async Task ProcessAlarmData(byte[] buffer, ClientState client)
  579. {
  580. var alarmData = ReceiveAlarmData(buffer);
  581. if (alarmData != null)
  582. {
  583. //处理报警数据
  584. AlarmDataReceived?.Invoke(this, new AlarmDataReceivedEventArgs(client.IpAddress, alarmData));
  585. }
  586. await Task.CompletedTask;
  587. }
  588. private async Task ProcessSyncParameters(byte[] data, ClientState client)
  589. {
  590. var (serialNo, parametersData) = ReceiveSyncParameters(data);
  591. if (parametersData != null)
  592. {
  593. var equipmentData = App.Config.Equipments.FirstOrDefault(c => c.IpAddress == client.IpAddress);
  594. if (equipmentData != null)
  595. {
  596. equipmentData.SerialNo = serialNo;
  597. equipmentData.Parameter = parametersData;
  598. await Task.Run(() =>
  599. {
  600. lock (App.Config.Equipments)
  601. {
  602. ConfigHelper.SetEquipment(equipmentData);
  603. }
  604. });
  605. }
  606. }
  607. }
  608. private async Task ProcessDetectionStatus(byte[] buffer, ClientState client)
  609. {
  610. byte code = ReceiveStartOrStopDetectionResultData(buffer);
  611. if (code == 0)
  612. {
  613. // 启动/停止检测结果,0=成功,>0=失败-原因码
  614. DetectionStatusResultReceived?.Invoke(this,
  615. new DetectionStatusResultReceivedEventArgs(client.IpAddress, code));
  616. }
  617. else
  618. {
  619. LogHelper.Error($"启动/停止检测结果失败,原因码:{code}");
  620. }
  621. await Task.CompletedTask;
  622. }
  623. public async Task ProcessUpgradedData(byte[] buffer, ClientState client)
  624. {
  625. byte code = ReceiveUpgradedResultData(buffer);
  626. // 程序更新请求,0=成功,>0=拒绝-原因码
  627. UpgradedRequestResultReceived?.Invoke(this,
  628. new UpgradedResultReceivedEventArgs(client.IpAddress, code));
  629. await Task.CompletedTask;
  630. }
  631. public byte ReceiveTurnLiveStreamData(byte[] buffer)
  632. {
  633. (string serialNo, byte[] bytes) = GetSerialNoAndData(buffer);
  634. return bytes[0];
  635. }
  636. public byte ReceiveOpenOrClosedRealtimeData(byte[] buffer)
  637. {
  638. (string serialNo, byte[] bytes) = GetSerialNoAndData(buffer);
  639. return bytes[0]; // 开启/关闭结果,0=成功,>0=失败-原因码
  640. }
  641. private DateTime? _lastLiveStreamReceiveTime = null;
  642. public LiveStreamDataModel ReceiveLiveStreamDataModel(byte[] buffer)
  643. {
  644. (string serialNo, byte[] bytes) = GetSerialNoAndData(buffer);
  645. var liveStreamData = new LiveStreamDataModel()
  646. {
  647. SensorCount = bytes[0],
  648. SampleCount = _byteTransform.TransUInt16(bytes, 1)
  649. };
  650. var data = bytes.Skip(3).ToArray(); // 跳过前3个字节
  651. liveStreamData.Data = ParseSensorData(data, liveStreamData.SensorCount, liveStreamData.SampleCount);
  652. // 计算本次接收与上次接收的时间差(毫秒)
  653. var now = DateTime.Now;
  654. if (_lastLiveStreamReceiveTime.HasValue)
  655. {
  656. liveStreamData.SampleInterval = (int)(now - _lastLiveStreamReceiveTime.Value).TotalMilliseconds;
  657. }
  658. _lastLiveStreamReceiveTime = now;
  659. return liveStreamData;
  660. }
  661. public TwistFactorDataModel ReceiveTwistFactorData(byte[] buffer)
  662. {
  663. (string serialNo, byte[] bytes) = GetSerialNoAndData(buffer);
  664. var twistFactorData = new TwistFactorDataModel
  665. {
  666. Type = bytes[0],
  667. TwistFactor = _byteTransform.TransSingle(bytes, 1) // 判伤捻距系数
  668. };
  669. return twistFactorData;
  670. }
  671. /// <summary>
  672. /// 发送获取编码器方向请求
  673. /// </summary>
  674. /// <param name="serialNo"></param>
  675. /// <param name="client"></param>
  676. /// <returns></returns>
  677. [Obfuscation(Feature = "virtualization", Exclude = false)]
  678. public bool SendGetEncoderDirectionData(string serialNo, Socket clientSocket)
  679. {
  680. try
  681. {
  682. if (clientSocket == null || !clientSocket.Connected)
  683. return false;
  684. // 获取不含端口的IP地址
  685. string ipAddress = ((IPEndPoint)clientSocket.RemoteEndPoint).Address.ToString();
  686. using (var ms = new MemoryStream())
  687. {
  688. ms.WriteByte(0x00); // 操作,0 = 获取编码器方向,1 = 设置编码器方向
  689. ms.WriteByte(0x01); // 编码器方向,1=正向,2=反向
  690. byte[] buffer = CreateData(0x12, ms.ToArray(), serialNo);
  691. DebugMessageReceived?.Invoke(this, new DebugMessageReceivedEventArgs($"获取设备编码器方向", ipAddress: ipAddress, serialNo: serialNo));
  692. clientSocket.Send(buffer);
  693. return true;
  694. }
  695. }
  696. catch (Exception ex)
  697. {
  698. LogHelper.Error("发送获取编码器方向数据命令时错误", ex);
  699. return false;
  700. }
  701. }
  702. /// <summary>
  703. /// 发送设置编码器方向数据命令
  704. /// </summary>
  705. /// <param name="direction"></param>
  706. /// <param name="serialNo"></param>
  707. /// <param name="stream"></param>
  708. /// <returns></returns>
  709. [Obfuscation(Feature = "virtualization", Exclude = false)]
  710. public bool SendSetEncoderDirectionData(EncoderDirection direction, string serialNo, Socket clientSocket)
  711. {
  712. try
  713. {
  714. if (clientSocket == null || !clientSocket.Connected)
  715. return false;
  716. // 获取不含端口的IP地址
  717. string ipAddress = ((IPEndPoint)clientSocket.RemoteEndPoint).Address.ToString();
  718. using (var ms = new MemoryStream())
  719. {
  720. ms.WriteByte(0x01); // 操作,0 = 获取编码器方向,1 = 设置编码器方向
  721. ms.WriteByte((byte)direction); // 编码器方向,1=正向,2=反向
  722. byte[] buffer = CreateData(0x12, ms.ToArray(), serialNo);
  723. DebugMessageReceived?.Invoke(this, new DebugMessageReceivedEventArgs($"设置设备编码器方向", ipAddress: ipAddress, serialNo: serialNo));
  724. clientSocket.Send(buffer);
  725. return true;
  726. }
  727. }
  728. catch (Exception ex)
  729. {
  730. LogHelper.Error("发送设置编码器方向数据命令时错误", ex);
  731. return false;
  732. }
  733. }
  734. /// <summary>
  735. /// 发送检测结果原始数据请求
  736. /// </summary>
  737. /// <param name="serialNo"></param>
  738. /// <param name="clientSocket"></param>
  739. /// <returns></returns>
  740. [Obfuscation(Feature = "virtualization", Exclude = false)]
  741. private bool SendGetDetectionRawData(string serialNo, Socket clientSocket)
  742. {
  743. try
  744. {
  745. if (clientSocket == null || !clientSocket.Connected)
  746. return false;
  747. // 获取不含端口的IP地址
  748. string ipAddress = ((IPEndPoint)clientSocket.RemoteEndPoint).Address.ToString();
  749. using (var ms = new MemoryStream())
  750. {
  751. ms.WriteByte(0); // 数据类型,0=正常,1=报警,2=故障
  752. WriteBytes(ms, (short)2048); // 单包数据大小,单位:Byte
  753. ms.WriteByte(0x00); // 传输速度控制,单位:KB/s(B/ms),为0则不控速
  754. byte[] buffer = CreateData(0x0E, ms.ToArray(), serialNo);
  755. DebugMessageReceived?.Invoke(this, new DebugMessageReceivedEventArgs($"获取检测结果原始数据",
  756. ipAddress: ipAddress,
  757. serialNo: serialNo));
  758. clientSocket.Send(buffer);
  759. return true;
  760. }
  761. }
  762. catch (Exception ex)
  763. {
  764. LogHelper.Error("发送获取编码器方向数据命令时错误", ex);
  765. return false;
  766. }
  767. }
  768. /// <summary>
  769. /// 接收获取原始数据结果
  770. /// </summary>
  771. /// <param name="buffer"></param>
  772. /// <returns></returns>
  773. [Obfuscation(Feature = "virtualization", Exclude = false)]
  774. public DetectionRawResultDataModel ReceiveDetectionRawResultData(byte[] buffer)
  775. {
  776. (string serialNo, byte[] bytes) = GetSerialNoAndData(buffer);
  777. var detectionRawResultData = new DetectionRawResultDataModel
  778. {
  779. Code = bytes[0],
  780. Timestamp = _byteTransform.TransInt32(bytes, 1),
  781. SamplingStep = _byteTransform.TransSingle(bytes, 5),
  782. StartAbsolutePosition = _byteTransform.TransSingle(bytes, 9),
  783. EndAbsolutePosition = _byteTransform.TransSingle(bytes, 13),
  784. SensorCount = bytes[17]
  785. };
  786. return detectionRawResultData;
  787. }
  788. /// <summary>
  789. /// 获取原始数据包
  790. /// </summary>
  791. /// <param name="buffer"></param>
  792. /// <returns></returns>
  793. [Obfuscation(Feature = "virtualization", Exclude = false)]
  794. public DetectionRawDataModel ReceiveDetectionRawData(byte[] buffer)
  795. {
  796. (string serialNo, byte[] bytes) = GetSerialNoAndData(buffer);
  797. var detectionRawData = new DetectionRawDataModel
  798. {
  799. PacketNumber = _byteTransform.TransUInt32(bytes, 0),
  800. TotalPackets = _byteTransform.TransUInt32(bytes, 4),
  801. DataLength = _byteTransform.TransUInt16(bytes, 8),
  802. Data = bytes.Skip(10).ToArray() // 跳过前10个字节
  803. };
  804. return detectionRawData;
  805. }
  806. /// <summary>
  807. /// 发送开启实时流数据命令
  808. /// </summary>
  809. /// <param name="isOpen">是否开启</param>
  810. /// <param name="serialNo">设备序列号</param>
  811. /// <param name="clientSocket"></param>
  812. /// <returns></returns>
  813. [Obfuscation(Feature = "virtualization", Exclude = false)]
  814. public bool SendTurnLiveStreamData(bool isOpen, string serialNo, Socket clientSocket)
  815. {
  816. try
  817. {
  818. if (clientSocket == null || !clientSocket.Connected)
  819. return false;
  820. // 获取不含端口的IP地址
  821. string ipAddress = ((IPEndPoint)clientSocket.RemoteEndPoint).Address.ToString();
  822. using (var ms = new MemoryStream())
  823. {
  824. ms.WriteByte((byte)(isOpen ? 1 : 0)); // 0=关闭,1=开启
  825. byte[] buffer = CreateData(0x0C, ms.ToArray(), serialNo);
  826. DebugMessageReceived?.Invoke(this, new DebugMessageReceivedEventArgs($"{(isOpen ? "开启" : "关闭")}设备实时流",
  827. ipAddress: ipAddress,
  828. serialNo: serialNo));
  829. clientSocket.Send(buffer);
  830. return true;
  831. }
  832. }
  833. catch (Exception ex)
  834. {
  835. LogHelper.Error("发送开启实时流数据命令时错误", ex);
  836. return false;
  837. }
  838. }
  839. /// <summary>
  840. /// 发送获取判伤捻距系数数据命令
  841. /// </summary>
  842. /// <param name="serialNo"></param>
  843. /// <param name="client"></param>
  844. /// <returns></returns>
  845. public bool SendGetTwistFactorData(string serialNo, Socket clientSocket)
  846. {
  847. try
  848. {
  849. if (clientSocket == null || !clientSocket.Connected)
  850. return false;
  851. // 获取不含端口的IP地址
  852. string ipAddress = ((IPEndPoint)clientSocket.RemoteEndPoint).Address.ToString();
  853. using (var ms = new MemoryStream())
  854. {
  855. ms.WriteByte(0x00); // 操作,0=获取判伤捻距系数,1=设置判伤捻距系数
  856. WriteBytes(ms, 0); // 判伤捻距系数
  857. byte[] buffer = CreateData(0x13, ms.ToArray(), serialNo);
  858. clientSocket.Send(buffer);
  859. return true;
  860. }
  861. }
  862. catch (Exception ex)
  863. {
  864. LogHelper.Error("发送获取判伤捻距系数数据命令时错误", ex);
  865. return false;
  866. }
  867. }
  868. /// <summary>
  869. /// 设置判伤捻距系数
  870. /// </summary>
  871. /// <param name="twistFactor"></param>
  872. /// <param name="serialNo"></param>
  873. /// <param name="clientSocket"></param>
  874. /// <returns></returns>
  875. public bool SendSetTwistFactorData(float twistFactor, string serialNo, Socket clientSocket)
  876. {
  877. try
  878. {
  879. if (clientSocket == null || !clientSocket.Connected)
  880. return false;
  881. using (var ms = new MemoryStream())
  882. {
  883. ms.WriteByte(0x01); // 操作,0=获取判伤捻距系数,1=设置判伤捻距系数
  884. WriteBytes(ms, twistFactor); // 判伤捻距系数
  885. byte[] buffer = CreateData(0x13, ms.ToArray(), serialNo);
  886. DebugMessageReceived?.Invoke(this, new DebugMessageReceivedEventArgs($"设置设备判伤捻距系数", serialNo: serialNo));
  887. clientSocket.Send(buffer);
  888. return true;
  889. }
  890. }
  891. catch (Exception ex)
  892. {
  893. LogHelper.Error("发送设置判伤捻距系数数据命令时错误", ex);
  894. return false;
  895. }
  896. }
  897. /// <summary>
  898. /// 返回编码器方向
  899. /// </summary>
  900. /// <param name="buffer"></param>
  901. /// <returns></returns>
  902. public EncoderDirectionDataModel ReceiveEncoderDirectionData(byte[] buffer)
  903. {
  904. (string serialNo, byte[] bytes) = GetSerialNoAndData(buffer);
  905. var encoderDirection = new EncoderDirectionDataModel
  906. {
  907. Code = bytes[0],
  908. Type = bytes[1],
  909. Direction = (EncoderDirection)bytes[2] // 编码器方向,1=正向,2=反向
  910. };
  911. return encoderDirection;
  912. }
  913. /// <summary>
  914. /// 接收返回系统时钟数据
  915. /// </summary>
  916. /// <param name="buffer"></param>
  917. /// <returns></returns>
  918. public ClockDataModel ReceiveClockData(byte[] buffer)
  919. {
  920. (string serialNo, byte[] bytes) = GetSerialNoAndData(buffer);
  921. ClockDataModel clockData = new ClockDataModel
  922. {
  923. Code = bytes[0],
  924. Type = bytes[1],
  925. Time = _byteTransform.TransInt32(bytes, 2)
  926. };
  927. return clockData;
  928. }
  929. /// <summary>
  930. /// 主板复位应答
  931. /// </summary>
  932. /// <param name="buffer"></param>
  933. /// <returns></returns>
  934. public ResetSystemDataModel ReceiveResetSystemData(byte[] buffer)
  935. {
  936. (string serialNo, byte[] bytes) = GetSerialNoAndData(buffer);
  937. var resetSystemData = new ResetSystemDataModel
  938. {
  939. Code = bytes[0]
  940. };
  941. return resetSystemData;
  942. }
  943. /// <summary>
  944. /// 设置当前实时位置应答
  945. /// </summary>
  946. /// <param name="buffer"></param>
  947. /// <returns></returns>
  948. public SetAbsolutePositionDataModel ReceiveSetAbsolutePositionData(byte[] buffer)
  949. {
  950. (string serialNo, byte[] bytes) = GetSerialNoAndData(buffer);
  951. var setAbsolutePositionData = new SetAbsolutePositionDataModel
  952. {
  953. Code = bytes[0]
  954. };
  955. return setAbsolutePositionData;
  956. }
  957. /// <summary>
  958. /// 发送获取时钟数据命令
  959. /// </summary>
  960. /// <param name="serialNo"></param>
  961. /// <param name="stream"></param>
  962. /// <returns></returns>
  963. public bool SendGetClockData(string serialNo, Socket clientSocket)
  964. {
  965. try
  966. {
  967. if (clientSocket == null || !clientSocket.Connected)
  968. return false;
  969. // 获取不含端口的IP地址
  970. string ipAddress = ((IPEndPoint)clientSocket.RemoteEndPoint).Address.ToString();
  971. using (var ms = new MemoryStream())
  972. {
  973. ms.WriteByte(0x00); // 操作,0=获取时钟,1=设置时钟
  974. WriteBytes(ms, 0);// 设置时间戳
  975. byte[] buffer = CreateData(0x10, ms.ToArray(), serialNo);
  976. DebugMessageReceived?.Invoke(this, new DebugMessageReceivedEventArgs($"获取设备时钟", ipAddress: ipAddress, serialNo: serialNo));
  977. clientSocket.Send(buffer);
  978. return true;
  979. }
  980. }
  981. catch (Exception ex)
  982. {
  983. LogHelper.Error("发送获取时钟数据命令时错误", ex);
  984. return false;
  985. }
  986. }
  987. /// <summary>
  988. /// 发送设置时钟数据命令
  989. /// </summary>
  990. /// <param name="timestamp">时间戳</param>
  991. /// <param name="serialNo">序列号</param>
  992. /// <param name="clientSocket">网络数据流</param>
  993. /// <returns></returns>
  994. public bool SendSetClockData(int timestamp, string serialNo, Socket clientSocket)
  995. {
  996. try
  997. {
  998. if (clientSocket == null || !clientSocket.Connected)
  999. return false;
  1000. // 获取不含端口的IP地址
  1001. string ipAddress = ((IPEndPoint)clientSocket.RemoteEndPoint).Address.ToString();
  1002. using (var ms = new MemoryStream())
  1003. {
  1004. ms.WriteByte(0x01); // 操作,0=获取时钟,1=设置时钟
  1005. WriteBytes(ms, timestamp);// 设置时间戳
  1006. byte[] buffer = CreateData(0x10, ms.ToArray(), serialNo);
  1007. DebugMessageReceived?.Invoke(this, new DebugMessageReceivedEventArgs($"设置设备时钟",
  1008. ipAddress: ipAddress,
  1009. serialNo: serialNo));
  1010. clientSocket.Send(buffer);
  1011. return true;
  1012. }
  1013. }
  1014. catch (Exception ex)
  1015. {
  1016. LogHelper.Error("发送设置时钟数据命令时错误", ex);
  1017. return false;
  1018. }
  1019. }
  1020. /// <summary>
  1021. /// 接收实时数据
  1022. /// </summary>
  1023. /// <param name="buffer"></param>
  1024. /// <returns></returns>
  1025. public RealTimeDataModel ReceiveRealTimeData(byte[] buffer)
  1026. {
  1027. (string serialNo, byte[] bytes) = GetSerialNoAndData(buffer);
  1028. RealTimeDataModel realTimeData = new RealTimeDataModel
  1029. {
  1030. Status = (RunningStatus)bytes[0],
  1031. Speed = _byteTransform.TransSingle(bytes, 1),
  1032. AbsolutePosition = _byteTransform.TransSingle(bytes, 5),
  1033. Position = _byteTransform.TransSingle(bytes, 9)
  1034. };
  1035. return realTimeData;
  1036. }
  1037. /// <summary>
  1038. /// 接收检测结果
  1039. /// </summary>
  1040. /// <param name="buffer"></param>
  1041. /// <returns></returns>
  1042. public DetectionDataModel ReceiveDetectionData(byte[] buffer)
  1043. {
  1044. var verifyData = GetVerifyDataAndCheckCaption(buffer);
  1045. if (!verifyData.IsValid)
  1046. {
  1047. LogHelper.Error("接收检测结果时验证码校验失败");
  1048. return null;
  1049. }
  1050. var data = verifyData.Data;
  1051. DetectionDataModel detectionData = new DetectionDataModel
  1052. {
  1053. StartTime = _byteTransform.TransInt32(data, 0),
  1054. EndTime = _byteTransform.TransInt32(data, 4),
  1055. StartPoint = _byteTransform.TransSingle(data, 8),
  1056. EndPoint = _byteTransform.TransSingle(data, 12),
  1057. DetectionLength = _byteTransform.TransSingle(data, 16),
  1058. DetectedSpeed = _byteTransform.TransSingle(data, 20),
  1059. DamageCount = _byteTransform.TransInt16(data, 24),
  1060. Damages = new List<DamageModel>()
  1061. };
  1062. for (int i = 0; i < detectionData.DamageCount; i++)
  1063. {
  1064. int offset = 26 + i * 10; // 每个损伤数据占8字节
  1065. if (offset + 10 > data.Length) break; // 防止越界
  1066. var damageData = new DamageModel
  1067. {
  1068. RopeNumber = data[offset],
  1069. DamagePoint = _byteTransform.TransSingle(data, offset + 1),
  1070. DamageValue = _byteTransform.TransSingle(data, offset + 5),
  1071. DamageLevel = (DamageLevel)data[offset + 9]
  1072. };
  1073. detectionData.Damages.Add(damageData);
  1074. }
  1075. return detectionData;
  1076. }
  1077. /// <summary>
  1078. /// 接收损伤信息
  1079. /// </summary>
  1080. /// <param name="buffer"></param>
  1081. /// <returns></returns>
  1082. public AlarmDataModel ReceiveAlarmData(byte[] buffer)
  1083. {
  1084. var verifyData = GetVerifyDataAndCheckCaption(buffer);
  1085. if (!verifyData.IsValid)
  1086. {
  1087. LogHelper.Error("接收同步参数时验证码校验失败");
  1088. return null;
  1089. }
  1090. var data = verifyData.Data;
  1091. AlarmDataModel alarmData = new AlarmDataModel
  1092. {
  1093. RopeNumber = data[1],
  1094. DamagePosition = _byteTransform.TransSingle(data, 2),
  1095. DamageValue = _byteTransform.TransSingle(data, 6),
  1096. DamageLevel = (DamageLevel)data[10]
  1097. };
  1098. return alarmData;
  1099. }
  1100. /// <summary>
  1101. /// 接收故障信息
  1102. /// </summary>
  1103. /// <param name="buffer"></param>
  1104. /// <returns></returns>
  1105. public FaultDataModel ReceiveFaultData(byte[] buffer)
  1106. {
  1107. var verifyData = GetVerifyDataAndCheckCaption(buffer);
  1108. if (!verifyData.IsValid)
  1109. {
  1110. LogHelper.Error("接收设备故障时验证码校验失败");
  1111. return null;
  1112. }
  1113. FaultDataModel faultData = new FaultDataModel();
  1114. var data = verifyData.Data;
  1115. faultData.FaultType = (FaultType)data[0];
  1116. faultData.FaultCode = _byteTransform.TransInt32(data, 1);
  1117. return faultData;
  1118. }
  1119. public byte ReceiveStartOrStopDetectionResultData(byte[] buffer)
  1120. {
  1121. (string serialNo, byte[] bytes) = GetSerialNoAndData(buffer);
  1122. return bytes[0];
  1123. }
  1124. public byte ReceiveUpgradedResultData(byte[] buffer)
  1125. {
  1126. (string serialNo, byte[] bytes) = GetSerialNoAndData(buffer);
  1127. return bytes[0];
  1128. }
  1129. public byte ReceiveChangeSerialNoResultData(byte[] buffer)
  1130. {
  1131. (string serialNo, byte[] bytes) = GetSerialNoAndData(buffer);
  1132. return bytes[0];
  1133. }
  1134. /// <summary>
  1135. /// 回复心跳
  1136. /// </summary>
  1137. /// <returns></returns>
  1138. private void RespondHeartbeat(byte[] buffer, string ipAddress, Socket clientSocket)
  1139. {
  1140. try
  1141. {
  1142. if (buffer[1] == 0x00)
  1143. {
  1144. byte[] response = new byte[] { 0xD0, 0x00 };
  1145. clientSocket?.Send(response); // 直接使用Socket发送
  1146. }
  1147. }
  1148. // 设备刚断开时回复心跳会抛 SocketException(对端重置),
  1149. // 就地吞掉即可,后续接收回调会走正常断开流程
  1150. catch (SocketException) { }
  1151. catch (ObjectDisposedException) { }
  1152. }
  1153. private async Task ProcessSerialNoData(byte[] buffer, ClientState client)
  1154. {
  1155. byte code = ReceiveChangeSerialNoResultData(buffer);
  1156. if (code == 0)
  1157. {
  1158. DebugMessageReceived?.Invoke(this, new DebugMessageReceivedEventArgs($"修改设备序列号成功", serialNo: client.SerialNo));
  1159. }
  1160. else
  1161. {
  1162. LogHelper.Error($"修改设备序列号结果失败,原因码:{code}");
  1163. }
  1164. await Task.CompletedTask;
  1165. }
  1166. /// <summary>
  1167. /// 接收同步参数
  1168. /// </summary>
  1169. /// <param name="buffer"></param>
  1170. /// <returns></returns>
  1171. public (string SerialNo, ParameterModel Parameter) ReceiveSyncParameters(byte[] buffer)
  1172. {
  1173. ParameterModel parameterData = new ParameterModel();
  1174. var verifyData = GetVerifyDataAndCheckCaption(buffer);
  1175. if (!verifyData.IsValid)
  1176. {
  1177. LogHelper.Error("接收同步参数时验证码校验失败");
  1178. return (null, null);
  1179. }
  1180. byte[] data = verifyData.Data;
  1181. int index = 0;
  1182. #region 主板软件版本号
  1183. short versionLength = data[index]; index += 1;
  1184. if (data.Length - index < versionLength)
  1185. return (null, null);
  1186. parameterData.MainBoardSoftwareVersion = Encoding.ASCII.GetString(data.Skip(index).Take(versionLength).ToArray());
  1187. index += versionLength;
  1188. #endregion
  1189. #region 基础参数
  1190. parameterData.SensorCount = _byteTransform.TransInt16(data, index); index += 2;
  1191. parameterData.SamplingStep = _byteTransform.TransSingle(data, index); index += 4;
  1192. parameterData.FrequencyDivisionFactor = _byteTransform.TransInt16(data, index); index += 2;
  1193. parameterData.DamageInterval = _byteTransform.TransInt16(data, index); index += 2;
  1194. #endregion
  1195. #region 判伤参数
  1196. parameterData.DamageThreshold = _byteTransform.TransInt16(data, index); index += 2;
  1197. parameterData.ScrapUpperLimit = _byteTransform.TransInt16(data, index); index += 2;
  1198. parameterData.FrontMagnetLength = _byteTransform.TransInt16(data, index); index += 2;
  1199. parameterData.BackMagnetLength = _byteTransform.TransInt16(data, index); index += 2;
  1200. parameterData.ValueCoefficient = _byteTransform.TransSingle(data, index); index += 4;
  1201. #endregion
  1202. #region 零点位参数
  1203. parameterData.EffectiveStrokeLength = _byteTransform.TransSingle(data, index); index += 4;
  1204. parameterData.ZeroPositionCorrectionDuration = _byteTransform.TransInt16(data, index); index += 2;
  1205. parameterData.ZeroPositionCorrectionOffset = _byteTransform.TransInt16(data, index); index += 2;
  1206. #endregion
  1207. #region 报警参数
  1208. parameterData.WarningValue = _byteTransform.TransSingle(data, index); index += 4;
  1209. parameterData.AlarmValue = _byteTransform.TransSingle(data, index); index += 4;
  1210. parameterData.SoundLightAlarmAutoResetMode = _byteTransform.TransInt16(data, index); index += 2;
  1211. #endregion
  1212. #region 钢丝绳信息
  1213. parameterData.WireRopeType = _byteTransform.TransInt16(data, index); index += 2;
  1214. parameterData.WireRopeCount = _byteTransform.TransInt16(data, index); index += 2;
  1215. parameterData.WireRopeLength = _byteTransform.TransSingle(data, index); index += 4;
  1216. parameterData.WireRopeDiameter = _byteTransform.TransSingle(data, index); index += 4;
  1217. parameterData.WireRopeStrandCount = _byteTransform.TransInt16(data, index); index += 2;
  1218. parameterData.WireRopeStrandWireCount = _byteTransform.TransInt16(data, index); index += 2;
  1219. #endregion
  1220. #region 限位校准位置
  1221. parameterData.FirstCalibrationPositiont = _byteTransform.TransSingle(data, index); index += 4;
  1222. parameterData.SecondCalibrationPositiont = _byteTransform.TransSingle(data, index); index += 4;
  1223. #endregion
  1224. return (verifyData.SerialNo, parameterData);
  1225. }
  1226. /// <summary>
  1227. /// 发送同步参数
  1228. /// </summary>
  1229. /// <param name="parameterData"></param>
  1230. /// <returns></returns>
  1231. public bool SendSyncParameters(ParameterModel parameters, string serialNo, Socket clientSocket)
  1232. {
  1233. try
  1234. {
  1235. if (clientSocket == null || !clientSocket.Connected)
  1236. return false;
  1237. using (var ms = new MemoryStream())
  1238. {
  1239. // Basic parameters
  1240. WriteBytes(ms, parameters.SensorCount);
  1241. WriteBytes(ms, parameters.SamplingStep);
  1242. WriteBytes(ms, parameters.FrequencyDivisionFactor);
  1243. WriteBytes(ms, parameters.DamageInterval);
  1244. // Damage judgment parameters
  1245. WriteBytes(ms, parameters.DamageThreshold);
  1246. WriteBytes(ms, parameters.ScrapUpperLimit);
  1247. WriteBytes(ms, parameters.FrontMagnetLength);
  1248. WriteBytes(ms, parameters.BackMagnetLength);
  1249. WriteBytes(ms, parameters.ValueCoefficient);
  1250. // Zero position parameters
  1251. WriteBytes(ms, parameters.EffectiveStrokeLength);
  1252. WriteBytes(ms, parameters.ZeroPositionCorrectionDuration);
  1253. WriteBytes(ms, parameters.ZeroPositionCorrectionOffset);
  1254. // Alarm parameters
  1255. WriteBytes(ms, parameters.WarningValue);
  1256. WriteBytes(ms, parameters.AlarmValue);
  1257. WriteBytes(ms, (ushort)parameters.SoundLightAlarmAutoResetMode);
  1258. // Wire rope info
  1259. WriteBytes(ms, parameters.WireRopeType);
  1260. WriteBytes(ms, parameters.WireRopeCount);
  1261. WriteBytes(ms, parameters.WireRopeLength);
  1262. WriteBytes(ms, parameters.WireRopeDiameter);
  1263. WriteBytes(ms, parameters.WireRopeStrandCount);
  1264. WriteBytes(ms, parameters.WireRopeStrandWireCount);
  1265. // Calibration Info
  1266. WriteBytes(ms, parameters.FirstCalibrationPositiont);
  1267. WriteBytes(ms, parameters.SecondCalibrationPositiont);
  1268. var buffer = CreateData(0x02, ms.ToArray(), serialNo);
  1269. DebugMessageReceived?.Invoke(this, new DebugMessageReceivedEventArgs($"同步设备参数", serialNo: serialNo));
  1270. clientSocket.Send(buffer);
  1271. return true;
  1272. }
  1273. }
  1274. catch (Exception ex)
  1275. {
  1276. LogHelper.Error("发送同步参数时错误", ex);
  1277. return false;
  1278. }
  1279. }
  1280. /// <summary>
  1281. /// 发送开始或停止检测命令
  1282. /// </summary>
  1283. /// <param name="runningMode">检测模式 0=停止,1=启动空域检测,2=启动时域检测</param>
  1284. /// <param name="serialNo">设备序列号</param>
  1285. /// <param name="clientSocket">数据流</param>
  1286. public bool SendStartOrStopDetection(byte runningMode, string serialNo, Socket clientSocket)
  1287. {
  1288. try
  1289. {
  1290. if (clientSocket == null || !clientSocket.Connected)
  1291. return false;
  1292. using (var ms = new MemoryStream())
  1293. {
  1294. ms.WriteByte(runningMode);// 0 = 停止,1 = 启动空域检测,2 = 启动时域检测
  1295. byte[] buffer = CreateData(0x06, ms.ToArray(), serialNo);
  1296. DebugMessageReceived?.Invoke(this, new DebugMessageReceivedEventArgs($"{(runningMode == 0 ? "停止" : "开始")}设备检测",
  1297. serialNo: serialNo));
  1298. clientSocket.Send(buffer);
  1299. return true;
  1300. }
  1301. }
  1302. catch (Exception ex)
  1303. {
  1304. LogHelper.Error("发送开始或停止检测命令时错误", ex);
  1305. return false;
  1306. }
  1307. }
  1308. /// <summary>
  1309. /// 发送修改设备序列号请求
  1310. /// </summary>
  1311. /// <param name="serialNo">设备序列号</param>
  1312. /// <param name="clientSocket">数据流</param>
  1313. /// <returns></returns>
  1314. public bool SendSerialNoRequest(string serialNo, Socket clientSocket)
  1315. {
  1316. try
  1317. {
  1318. if (clientSocket == null || !clientSocket.Connected || serialNo.IsNullOrEmpty())
  1319. return false;
  1320. using (var ms = new MemoryStream())
  1321. {
  1322. byte[] serialNoBytes = Encoding.UTF8.GetBytes(serialNo);
  1323. ms.WriteByte((byte)serialNoBytes.Length); // 序列号长度
  1324. ms.Write(serialNoBytes, 0, serialNoBytes.Length); // 序列号
  1325. byte[] buffer = CreateData(0x16, ms.ToArray(), serialNo);
  1326. DebugMessageReceived?.Invoke(this, new DebugMessageReceivedEventArgs($"请求修改设备序列号", serialNo: null));
  1327. clientSocket.Send(buffer);
  1328. return true;
  1329. }
  1330. }
  1331. catch (Exception ex)
  1332. {
  1333. LogHelper.Error("发送设备序列号请求命令时错误", ex);
  1334. return false;
  1335. }
  1336. }
  1337. /// <summary>
  1338. /// 发送程序更新请求
  1339. /// </summary>
  1340. /// <param name="serialNo">设备序列号</param>
  1341. /// <param name="clientSocket">数据流</param>
  1342. /// <returns></returns>
  1343. public bool SendUpgradeRequest(string serialNo, Socket clientSocket)
  1344. {
  1345. try
  1346. {
  1347. if (clientSocket == null || !clientSocket.Connected)
  1348. return false;
  1349. using (var ms = new MemoryStream())
  1350. {
  1351. ms.WriteByte(1);
  1352. byte[] buffer = CreateData(0x11, ms.ToArray(), serialNo);
  1353. DebugMessageReceived?.Invoke(this, new DebugMessageReceivedEventArgs($"发起程序更新请求", serialNo: serialNo));
  1354. clientSocket.Send(buffer);
  1355. return true;
  1356. }
  1357. }
  1358. catch (Exception ex)
  1359. {
  1360. LogHelper.Error("发送程序更新请求命令时错误", ex);
  1361. return false;
  1362. }
  1363. }
  1364. /// <summary>
  1365. /// 发送开始或停止实时数据
  1366. /// </summary>
  1367. /// <param name="isOpen">是否开启</param>
  1368. /// <param name="serialNo">序列号</param>
  1369. /// <param name="clientSocket"></param>
  1370. public void SendOpenOrClosedRealtimeData(bool isOpen, string serialNo, Socket clientSocket)
  1371. {
  1372. try
  1373. {
  1374. if (clientSocket == null || !clientSocket.Connected)
  1375. return;
  1376. string ipAddress = ((IPEndPoint)clientSocket.RemoteEndPoint).Address.ToString();
  1377. using (var ms = new MemoryStream())
  1378. {
  1379. ms.WriteByte((byte)(isOpen ? 1 : 0)); // 0=关闭,1=开启
  1380. byte[] buffer = CreateData(0x06, ms.ToArray(), serialNo);
  1381. DebugMessageReceived?.Invoke(this, new DebugMessageReceivedEventArgs($"{(isOpen ? "开启" : "停止")}设备实时数据",
  1382. ipAddress: ipAddress,
  1383. serialNo: serialNo));
  1384. clientSocket.Send(buffer);
  1385. }
  1386. }
  1387. catch (Exception ex)
  1388. {
  1389. LogHelper.Error("发送开始或停止实时数据命令时错误", ex);
  1390. }
  1391. }
  1392. private void SafeCloseClient(ClientState client)
  1393. {
  1394. if (client == null)
  1395. return;
  1396. try
  1397. {
  1398. ClientDisconnected?.Invoke(this, new ClientDisconnectedEventArgs(client.ClientSocket, client.IpAddress));
  1399. _connectedClients.TryRemove(client.IpAddress, out _);
  1400. var socket = client.ClientSocket;
  1401. client.ClientSocket = null;
  1402. if (socket != null)
  1403. {
  1404. try
  1405. {
  1406. socket.Shutdown(SocketShutdown.Both);
  1407. }
  1408. catch (SocketException) { }
  1409. catch (ObjectDisposedException) { }
  1410. socket.Close();
  1411. socket.Dispose();
  1412. }
  1413. }
  1414. catch (Exception ex)
  1415. {
  1416. Console.WriteLine($"关闭Socket时错误: {ex.Message}");
  1417. }
  1418. }
  1419. private void WriteBytes(MemoryStream ms, dynamic value)
  1420. {
  1421. var bytes = _byteTransform.TransByte(value);
  1422. ms.Write(bytes, 0, bytes.Length);
  1423. }
  1424. /// <summary>
  1425. /// 发送检测结果确认
  1426. /// </summary>
  1427. /// <param name="parameterData"></param>
  1428. /// <returns></returns>
  1429. public bool SendDetectionConfirm(int startTime, int endTime, string serialNo, Socket clientSocket)
  1430. {
  1431. try
  1432. {
  1433. if (clientSocket == null || !clientSocket.Connected)
  1434. return false;
  1435. string ipAddress = ((IPEndPoint)clientSocket.RemoteEndPoint).Address.ToString();
  1436. using (var ms = new MemoryStream())
  1437. {
  1438. WriteBytes(ms, startTime);
  1439. WriteBytes(ms, endTime);
  1440. byte[] buffer = CreateData(0x09, ms.ToArray(), serialNo);
  1441. DebugMessageReceived?.Invoke(this, new DebugMessageReceivedEventArgs($"确认设备检测结果", ipAddress: ipAddress, serialNo: serialNo));
  1442. clientSocket.Send(buffer);
  1443. return true;
  1444. }
  1445. }
  1446. catch (Exception ex)
  1447. {
  1448. LogHelper.Error("发送检测结果确认时错误", ex);
  1449. return false;
  1450. }
  1451. }
  1452. /// <summary>
  1453. /// 发送主板复位请求
  1454. /// </summary>
  1455. /// <param name="serialNo"></param>
  1456. /// <param name="clientSocket"></param>
  1457. /// <returns></returns>
  1458. public bool SendResetSystemData(string serialNo, Socket clientSocket)
  1459. {
  1460. try
  1461. {
  1462. if (clientSocket == null || !clientSocket.Connected)
  1463. return false;
  1464. using (var ms = new MemoryStream())
  1465. {
  1466. byte[] buffer = CreateData(0x14, ms.ToArray(), serialNo);
  1467. DebugMessageReceived?.Invoke(this, new DebugMessageReceivedEventArgs($"发送主板复位请求", serialNo: serialNo));
  1468. clientSocket.Send(buffer);
  1469. return true;
  1470. }
  1471. }
  1472. catch (Exception ex)
  1473. {
  1474. LogHelper.Error("发送主板复位请求时错误", ex);
  1475. return false;
  1476. }
  1477. }
  1478. /// <summary>
  1479. /// 发送设置当前实时位置
  1480. /// </summary>
  1481. /// <returns></returns>
  1482. public bool SendRealTimeAbsolutePositionData(int switchIndex, float absolutePosition, string serialNo, Socket clientSocket)
  1483. {
  1484. try
  1485. {
  1486. if (clientSocket == null || !clientSocket.Connected)
  1487. return false;
  1488. using (var ms = new MemoryStream())
  1489. {
  1490. ms.WriteByte((byte)switchIndex);// 0无关联开关 1 关联开关1 2关联开关2
  1491. WriteBytes(ms, absolutePosition);
  1492. byte[] buffer = CreateData(0x15, ms.ToArray(), serialNo);
  1493. DebugMessageReceived?.Invoke(this, new DebugMessageReceivedEventArgs($"发送设置当前实时位置请求", serialNo: serialNo));
  1494. clientSocket.Send(buffer);
  1495. return true;
  1496. }
  1497. }
  1498. catch (Exception ex)
  1499. {
  1500. LogHelper.Error("发送设置当前实时位置请求时错误", ex);
  1501. return false;
  1502. }
  1503. }
  1504. /// <summary>
  1505. /// 获取数据并验证验证码
  1506. /// </summary>
  1507. /// <param name="buffer">数据</param>
  1508. /// <returns></returns>
  1509. [Obfuscation(Feature = "virtualization", Exclude = false)]
  1510. private VerifyDataModel GetVerifyDataAndCheckCaption(byte[] buffer)
  1511. {
  1512. VerifyDataModel verifyData = new VerifyDataModel() { Password = PASSWORD };
  1513. // 使用Span直接操作内存
  1514. Span<byte> span = buffer.AsSpan();
  1515. // 移除事件类型
  1516. span = span.Slice(1);
  1517. // 读取序列号长度
  1518. if (span.IsEmpty) return verifyData;
  1519. int serialNoLength = span[0];
  1520. // 读取序列号
  1521. if (span.Length - 1 < serialNoLength) return verifyData;
  1522. verifyData.SerialNo = SoftBasic.GetAsciiStringRender(span.Slice(1, serialNoLength).ToArray());
  1523. span = span.Slice(1 + serialNoLength);
  1524. // 读取随机码
  1525. if (span.Length < 4) return verifyData;
  1526. verifyData.RandomCode = _byteTransform.TransUInt32(span.ToArray(), 0);
  1527. span = span.Slice(4);
  1528. // 读取验证码长度
  1529. if (span.IsEmpty) return verifyData;
  1530. int captchaLength = span[0];
  1531. // 验证验证码
  1532. if (span.Length - 1 < captchaLength) return verifyData;
  1533. verifyData.Captcha = SoftBasic.AsciiBytesToBytes(span.Slice(1, captchaLength).ToArray());
  1534. // 截取剩余数据
  1535. verifyData.Data = span.Slice(captchaLength + 1).ToArray();
  1536. // 校验验证码
  1537. verifyData.IsValid = VerifyCaptcha(verifyData);
  1538. return verifyData;
  1539. }
  1540. /// <summary>
  1541. /// 验证码校验
  1542. /// </summary>
  1543. /// <returns></returns>
  1544. [Obfuscation(Feature = "virtualization", Exclude = false)]
  1545. private static bool VerifyCaptcha(VerifyDataModel verifyData)
  1546. {
  1547. if (verifyData == null)
  1548. throw new ArgumentNullException(nameof(verifyData));
  1549. if (verifyData.Captcha == null || verifyData.Captcha.Length < 16)
  1550. return false;
  1551. byte[] computedHash;
  1552. using (var md5 = MD5.Create())
  1553. {
  1554. computedHash = md5.ComputeHash(
  1555. Encoding.UTF8.GetBytes(
  1556. verifyData.SerialNo + verifyData.Password + verifyData.RandomCode));
  1557. }
  1558. // 常量时间比较(手动实现)
  1559. return FixedTimeEquals(verifyData.Captcha, computedHash, 16);
  1560. }
  1561. /// <summary>
  1562. /// 常量时间比较两个字节数组,防止时序攻击
  1563. /// </summary>
  1564. private static bool FixedTimeEquals(byte[] a, byte[] b, int length)
  1565. {
  1566. if (a.Length < length || b.Length < length)
  1567. return false;
  1568. int result = 0;
  1569. for (int i = 0; i < length; i++)
  1570. {
  1571. result |= a[i] ^ b[i]; // XOR 操作,相同为0,不同为非0
  1572. }
  1573. return result == 0;
  1574. }
  1575. ///<summary>
  1576. ///创建数据验证码
  1577. ///</summary>
  1578. /// <returns></returns>
  1579. [Obfuscation(Feature = "virtualization", Exclude = false)]
  1580. protected byte[] CreateData(byte eventType, byte[] data, string serialNo)
  1581. {
  1582. using (var md5 = MD5.Create())
  1583. {
  1584. using (var ms = new MemoryStream())
  1585. {
  1586. // 1. 预先计算所有字段的长度
  1587. uint randomCode = (uint)DateTimeOffset.UtcNow.ToUnixTimeSeconds();
  1588. byte[] randomCodeBytes = _byteTransform.TransByte(randomCode);
  1589. byte[] hash = md5.ComputeHash(Encoding.ASCII.GetBytes(serialNo + PASSWORD + randomCode));
  1590. byte[] captcha = SoftBasic.BytesToAsciiBytes(hash);
  1591. // 2. 正确计算剩余长度(关键修正点)
  1592. // 剩余长度 = 事件类型(1) + 序列号长度(1) + 序列号数据 + 随机码 + 验证码长度(1) + 验证码 + 用户数据
  1593. short remainingLength = (short)(
  1594. 1 + // eventType
  1595. randomCodeBytes.Length + // 随机码(固定4字节)
  1596. 1 + captcha.Length + // 验证码(长度字节 + 数据)
  1597. data.Length // 用户数据
  1598. );
  1599. // 3. 写入头部(0x30 + 剩余长度)
  1600. ms.WriteByte(0x30);
  1601. if (remainingLength <= 127)
  1602. {
  1603. ms.WriteByte((byte)remainingLength); // 单字节表示
  1604. }
  1605. else
  1606. {
  1607. // 假设byteTransform.TransByte将short转为2字节大端序
  1608. byte[] remainingLengthBytes = _byteTransform.TransByte(remainingLength);
  1609. ms.Write(remainingLengthBytes, 0, remainingLengthBytes.Length);
  1610. }
  1611. // 4. 写入各字段(保持原逻辑)
  1612. ms.WriteByte(eventType);
  1613. ms.Write(randomCodeBytes, 0, randomCodeBytes.Length);
  1614. ms.WriteByte((byte)captcha.Length);
  1615. ms.Write(captcha, 0, captcha.Length);
  1616. ms.Write(data, 0, data.Length);
  1617. return ms.ToArray();
  1618. }
  1619. }
  1620. }
  1621. [Obfuscation(Feature = "virtualization", Exclude = false)]
  1622. public ushort[][] ParseSensorData(byte[] data, int sensorCount, int sampleCount)
  1623. {
  1624. // 检查数据长度是否匹配
  1625. int expectedLength = sensorCount * sampleCount;
  1626. if (data.Length != expectedLength)
  1627. {
  1628. LogHelper.Error($"数据长度不匹配。预期 {expectedLength} 字节,实际 {data.Length} 字节。");
  1629. return null;
  1630. }
  1631. // 初始化结果列表,每个传感器的数据存储在一个单独的 ushort[]
  1632. ushort[][] sensorDataList = new ushort[sampleCount][];
  1633. for (int i = 0; i < sampleCount; i++)
  1634. {
  1635. sensorDataList[i] = new ushort[sensorCount];
  1636. }
  1637. // 解析数据
  1638. for (int sampleIndex = 0; sampleIndex < sampleCount; sampleIndex++)
  1639. {
  1640. for (int sensorIndex = 0; sensorIndex < sensorCount; sensorIndex++)
  1641. {
  1642. // 计算数据在字节数组中的位置
  1643. int dataIndex = (sampleIndex * sensorCount) + sensorIndex;
  1644. // 将 byte 转换为 ushort(直接赋值,因为 byte 可以隐式转换为 ushort)
  1645. sensorDataList[sampleIndex][sensorIndex] = data[dataIndex];
  1646. }
  1647. }
  1648. return sensorDataList;
  1649. }
  1650. /// <summary>
  1651. /// 获取剩余长度
  1652. /// </summary>
  1653. /// <param name="bytes"></param>
  1654. /// <param name="startIndex"></param>
  1655. /// <returns></returns>
  1656. [Obfuscation(Feature = "virtualization", Exclude = false)]
  1657. public static (int BytesConsumed, int Length) GetRemainingLength(byte[] bytes)
  1658. {
  1659. if (bytes == null || bytes.Length < 2) return (0, 0);
  1660. int index = 1; // 跳过包类型字节
  1661. int multiplier = 1;
  1662. int value = 0;
  1663. byte encodedByte;
  1664. int bytesConsumed = 0;
  1665. do
  1666. {
  1667. if (index >= bytes.Length) return (0, 0);
  1668. encodedByte = bytes[index];
  1669. value += (encodedByte & 0x7F) * multiplier;
  1670. multiplier *= 128;
  1671. index++;
  1672. bytesConsumed++;
  1673. if (multiplier > 128 * 128 * 128) // 防止溢出
  1674. return (0, 0);
  1675. } while ((encodedByte & 0x80) != 0 && bytesConsumed < 4); // 最多4字节长度
  1676. return (bytesConsumed, value);
  1677. }
  1678. [Obfuscation(Feature = "virtualization", Exclude = false)]
  1679. private static (string SerialNo, byte[] Bytes) GetSerialNoAndData(byte[] buffer)
  1680. {
  1681. // 使用Span直接操作内存
  1682. Span<byte> span = buffer.AsSpan();
  1683. // 移除事件类型
  1684. span = span.Slice(1);
  1685. // 读取序列号长度
  1686. if (span.IsEmpty) return (null, null);
  1687. int serialNoLength = span[0];
  1688. // 读取序列号
  1689. if (span.Length - 1 < serialNoLength) return (null, null);
  1690. var serialNo = SoftBasic.GetAsciiStringRender(span.Slice(1, serialNoLength).ToArray());
  1691. buffer = span.Slice(1 + serialNoLength).ToArray();
  1692. return (serialNo, buffer);
  1693. }
  1694. public void Dispose()
  1695. {
  1696. try
  1697. {
  1698. _isRunning = false;
  1699. Thread.Sleep(100);
  1700. if (_listener != null)
  1701. {
  1702. if (_listener.Connected)
  1703. {
  1704. _listener.Shutdown(SocketShutdown.Both);
  1705. }
  1706. _listener.Close();
  1707. _listener.Dispose();
  1708. }
  1709. }
  1710. catch (SocketException ex) when (ex.SocketErrorCode == SocketError.NotConnected)
  1711. {
  1712. _listener?.Dispose();
  1713. }
  1714. catch (Exception ex)
  1715. {
  1716. LogHelper.Error($"停止服务时发生异常: {ex.Message}", ex);
  1717. }
  1718. finally
  1719. {
  1720. _listener = null;
  1721. }
  1722. }
  1723. }
  1724. }