TcpServerFrame.cs 75 KB

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