From b82f65075442bc48fe3930e5ec6d2bc6f062d81b Mon Sep 17 00:00:00 2001 From: zqm Date: Mon, 3 Nov 2025 09:16:09 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=B8=A9=E5=BA=A6=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E6=8E=A5=E6=94=B6=E5=BC=82=E5=B8=B8=EF=BC=8C=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E5=BF=83=E8=B7=B3=E6=9C=BA=E5=88=B6=E5=92=8C=E8=BF=9E?= =?UTF-8?q?=E6=8E=A5=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Toprie/Toprie/DeviceManager.cs | 130 ++++++++++++------ 1 file changed, 85 insertions(+), 45 deletions(-) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs b/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs index 86ef099..a4e4a6c 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs @@ -1129,10 +1129,11 @@ namespace JoyD.Windows.CS.Toprie byte[] buffer = new byte[65536]; // 缓冲区大小 // 定义常量 - const int RECEIVE_TIMEOUT = 5000; + const int RECEIVE_TIMEOUT = 30000; // 增加到30秒,减少因超时导致的断开 + const int HEARTBEAT_INTERVAL = 15000; // 心跳间隔15秒 const int MEDIUM_SLEEP_MS = 50; - const int LONG_SLEEP_MS = 1000; - const int ERROR_SLEEP_MS = 100; + const int LONG_SLEEP_MS = 2000; // 增加重连等待时间 + const int ERROR_SLEEP_MS = 1000; // 增加异常恢复等待时间 try { @@ -1255,55 +1256,94 @@ namespace JoyD.Windows.CS.Toprie _isReceivingTemperatureData = true; } + // 记录上次心跳时间和上次接收数据时间 + DateTime lastHeartbeatTime = DateTime.Now; + DateTime lastReceiveTime = DateTime.Now; + // 持续读取温度数据流 - while (localTcpClient != null && localTcpClient.Connected && !isPaused) + while (localTcpClient != null && localTcpClient.Connected) { - // 使用阻塞读取方式,等待数据到达 - int bytesRead = localStream.Read(buffer, 0, buffer.Length); - if (bytesRead > 0) + // 检查是否暂停 + lock (_lockObject) { - byte[] receivedBytes = new byte[bytesRead]; - Array.Copy(buffer, receivedBytes, bytesRead); - Log($"接收到温度数据字节数: {bytesRead}"); - - // 根据暂停状态决定是否处理数据 - if (isPaused) - { - Log("处于暂停状态,数据已接收但丢弃"); - } - else - { - // 同步接收并处理数据 - lock (temperatureDataAccumulator) - { - temperatureDataAccumulator.AddRange(receivedBytes); - ProcessReceivedTemperatureData(temperatureDataAccumulator); - } - } + isPaused = _isTemperatureReceivingPaused; } - else + + if (isPaused) { - // 连接已关闭 - Log("远程主机关闭了连接"); - - // 重置状态标志,下一次循环会创建新连接 - lock (_lockObject) - { - _isReceivingTemperatureData = false; - } - - // 清理连接资源 - try - { - localStream.Close(); - localTcpClient.Close(); - } - catch {} - - localStream = null; - localTcpClient = null; + Log("温度接收已暂停,等待恢复"); + Thread.Sleep(MEDIUM_SLEEP_MS); continue; } + + // 发送心跳保持连接 + if ((DateTime.Now - lastHeartbeatTime).TotalMilliseconds > HEARTBEAT_INTERVAL) + { + try + { + byte[] heartbeatCommand = Encoding.ASCII.GetBytes("heartbeat\r\n"); + localStream.Write(heartbeatCommand, 0, heartbeatCommand.Length); + localStream.Flush(); + lastHeartbeatTime = DateTime.Now; + // 心跳不记录日志以减少日志量 + } + catch (Exception ex) + { + Log($"发送心跳失败: {ex.Message}"); + } + } + + // 使用非阻塞方式检查是否有数据可读 + if (localStream.DataAvailable) + { + // 有数据可读时进行阻塞读取 + int bytesRead = localStream.Read(buffer, 0, buffer.Length); + if (bytesRead > 0) + { + lastReceiveTime = DateTime.Now; // 更新最后接收数据时间 + byte[] receivedBytes = new byte[bytesRead]; + Array.Copy(buffer, receivedBytes, bytesRead); + Log($"接收到温度数据字节数: {bytesRead}"); + + // 根据暂停状态决定是否处理数据 + if (isPaused) + { + Log("处于暂停状态,数据已接收但丢弃"); + } + else + { + // 同步接收并处理数据 + lock (temperatureDataAccumulator) + { + temperatureDataAccumulator.AddRange(receivedBytes); + ProcessReceivedTemperatureData(temperatureDataAccumulator); + } + } + } + else if (bytesRead == 0) + { + // 连接已关闭 + Log("远程主机关闭了连接"); + + // 重置状态标志,下一次循环会创建新连接 + lock (_lockObject) + { + _isReceivingTemperatureData = false; + } + + // 清理连接资源 + try + { + localStream.Close(); + localTcpClient.Close(); + } + catch {} + + localStream = null; + localTcpClient = null; + continue; + } + } } // while循环退出后的处理 }