修改优化连接逻辑

This commit is contained in:
zqm
2025-12-31 16:34:33 +08:00
parent 526ac86414
commit f4eaee6c61
2 changed files with 167 additions and 62 deletions

View File

@@ -2818,8 +2818,8 @@ namespace JoyD.Windows.CS.Toprie
if (!_showGlobalTemperature && !_showAreaTemperature)
return;
// 4. 如果勾选了全局温度,则显示全局温度(居中显示),否则显示区域温度(居中显示)
bool isGlobalTemperatureMode = _showGlobalTemperature;
// 4. 如果勾选了全局温度且未勾选区域温度,则显示全局温度(居中显示),否则显示区域温度(居中显示)
bool isGlobalTemperatureMode = _showGlobalTemperature && !_showAreaTemperature;
// 5. 如果勾选了区域温度,则显示区域框,否则不显示区域框
if (_showAreaTemperature)

View File

@@ -312,7 +312,16 @@ namespace JoyD.Windows.CS.Toprie
/// <returns>如果连接有效返回true否则返回false</returns>
private bool IsTcpClientConnected(TcpClient client)
{
if (client == null || !client.Connected)
// 基本检查
if (client == null)
return false;
// 检查底层Socket是否存在
if (client.Client == null)
return false;
// 首先检查Connected属性
if (!client.Connected)
return false;
// 检查连接状态的标准方法
@@ -321,21 +330,35 @@ namespace JoyD.Windows.CS.Toprie
{
// Poll方法检查连接状态100ms超时
// SelectMode.SelectRead检查是否可读
// 逻辑如果Poll返回true说明连接有活动
// 如果Poll返回false且Available > 0说明有数据可读
bool isConnected = !client.Client.Poll(100, System.Net.Sockets.SelectMode.SelectRead) ||
client.Client.Available > 0;
// 如果连接已断开Client.RemoteEndPoint会抛出异常
if (isConnected)
{
// 尝试访问RemoteEndPoint验证连接
var dummy = client.Client.RemoteEndPoint;
// 二次检查Connected属性确保连接没有在检查过程中断开
isConnected = client.Connected && client.Client.Connected;
}
return isConnected;
}
catch (ObjectDisposedException)
{
// Socket已被释放
return false;
}
catch (InvalidOperationException)
{
// Socket状态无效
return false;
}
catch
{
// 任何异常都表示连接可能已断开
// 任何其他异常都表示连接可能已断开
return false;
}
}
@@ -518,6 +541,7 @@ namespace JoyD.Windows.CS.Toprie
}
}
private TcpClient _imageTcpClient;
private TcpClient _temperatureTcpClient; // 用于跟踪当前活跃的温度数据TCP连接
// 使用CurrentImageMode代替_isInfraredMode
private static readonly object _logLock = new object();
@@ -1441,7 +1465,6 @@ namespace JoyD.Windows.CS.Toprie
Log($"[{DateTime.Now:HH:mm:ss.fff}] [线程:{Thread.CurrentThread.ManagedThreadId}] ReceiveTemperatureDataWithTcp() - 开始执行");
// 使用局部变量存储资源
TcpClient localTcpClient = null;
NetworkStream localStream = null;
List<byte[]> temperatureDataAccumulator = new List<byte[]>();
byte[] buffer = new byte[65536]; // 缓冲区大小
@@ -1471,7 +1494,9 @@ namespace JoyD.Windows.CS.Toprie
}
// 如果连接不存在或已断开,创建新连接
if (localTcpClient == null || !IsTcpClientConnected(localTcpClient))
lock (_lockObject)
{
if (_temperatureTcpClient == null || !IsTcpClientConnected(_temperatureTcpClient))
{
// 如果处于暂停状态则Sleep 1秒后继续执行
if (isPaused)
@@ -1484,12 +1509,23 @@ namespace JoyD.Windows.CS.Toprie
Log("创建新的温度数据TCP连接...");
// 清理之前可能存在的连接资源
CleanupConnectionResources(localStream, localTcpClient, out localStream, out localTcpClient);
if (_temperatureTcpClient != null)
{
try
{
_temperatureTcpClient.Close();
_temperatureTcpClient = null;
}
catch (Exception ex)
{
Log($"关闭现有TCP连接异常: {ex.Message}");
}
}
try
{
// 创建TCP客户端并连接
localTcpClient = new TcpClient
_temperatureTcpClient = new TcpClient
{
ReceiveTimeout = RECEIVE_TIMEOUT,
SendTimeout = RECEIVE_TIMEOUT,
@@ -1497,33 +1533,30 @@ namespace JoyD.Windows.CS.Toprie
};
Log($"正在连接到温度数据端口 {temperaturePort}...");
localTcpClient.Connect(deviceIp, temperaturePort);
_temperatureTcpClient.Connect(deviceIp, temperaturePort);
Log("温度数据TCP连接成功");
// 获取网络流
localStream = localTcpClient.GetStream();
localStream.ReadTimeout = RECEIVE_TIMEOUT;
// 根据SDK文档建立TCP连接后不需要发送任何开始命令
Log("TCP连接已建立等待接收温度数据...");
}
catch (Exception ex)
{
Log($"TCP连接或初始化失败: {ex.Message}");
_temperatureTcpClient = null;
// 连接失败后等待一段时间再重试
Thread.Sleep(LONG_SLEEP_MS);
continue;
}
}
}
// 数据接收处理:使用已建立的连接持续接收数据
if (localTcpClient != null && localTcpClient.Connected && localStream != null)
if (_temperatureTcpClient != null && _temperatureTcpClient.Connected)
{
try
{
// 获取网络流
localStream = _temperatureTcpClient.GetStream();
localStream.ReadTimeout = RECEIVE_TIMEOUT;
Log("TCP连接已建立等待接收温度数据...");
// 记录连接检查时间
DateTime lastConnectionCheckTime = DateTime.Now;
DateTime lastPausedLogTime = DateTime.MinValue;
@@ -1540,7 +1573,7 @@ namespace JoyD.Windows.CS.Toprie
}
// 持续读取温度数据流
while (localTcpClient != null && localTcpClient.Connected)
while (_temperatureTcpClient != null && _temperatureTcpClient.Connected)
{
// 每次循环开始时检查是否收到停止信号
if (ShouldStop())
@@ -1593,10 +1626,14 @@ namespace JoyD.Windows.CS.Toprie
// 在暂停状态下,降低连接检查频率
if ((currentTime - lastConnectionCheckTime).TotalMilliseconds > CONNECTION_CHECK_INTERVAL_MS)
{
if (localTcpClient != null && !IsTcpClientConnected(localTcpClient))
lock (_lockObject)
{
if (_temperatureTcpClient != null && !IsTcpClientConnected(_temperatureTcpClient))
{
Log("暂停状态下检测到连接已断开,将在恢复时重建连接");
CleanupConnectionResources(localStream, localTcpClient, out localStream, out localTcpClient);
_temperatureTcpClient.Close();
_temperatureTcpClient = null;
}
}
lastConnectionCheckTime = currentTime;
}
@@ -1605,13 +1642,17 @@ namespace JoyD.Windows.CS.Toprie
else
{
// 只有从暂停状态恢复时状态从true变为false的瞬间才检查和重建连接
if (pausedChanged && localTcpClient != null && !IsTcpClientConnected(localTcpClient))
lock (_lockObject)
{
if (pausedChanged && _temperatureTcpClient != null && !IsTcpClientConnected(_temperatureTcpClient))
{
Log("恢复接收时检测到连接无效,需要重建连接");
CleanupConnectionResources(localStream, localTcpClient, out localStream, out localTcpClient);
_temperatureTcpClient.Close();
_temperatureTcpClient = null;
// 跳出内层循环,回到外层循环重新建立连接
break;
}
}
// 根据SDK文档建立TCP连接后不需要发送任何开始命令
// 从暂停状态恢复时,只需继续监听数据流即可
if (pausedChanged)
@@ -1625,11 +1666,16 @@ namespace JoyD.Windows.CS.Toprie
DateTime now = DateTime.Now;
if ((now - lastConnectionCheckTime).TotalMilliseconds > CONNECTION_CHECK_INTERVAL_MS)
{
if (localTcpClient != null && !IsTcpClientConnected(localTcpClient))
lock (_lockObject)
{
if (_temperatureTcpClient != null && !IsTcpClientConnected(_temperatureTcpClient))
{
Log("检测到连接已断开,准备重建连接");
CleanupConnectionResources(localStream, localTcpClient, out localStream, out localTcpClient);
continue;
_temperatureTcpClient.Close();
_temperatureTcpClient = null;
// 跳出内层循环,回到外层循环重新建立连接
break;
}
}
lastConnectionCheckTime = now;
}
@@ -1672,8 +1718,15 @@ namespace JoyD.Windows.CS.Toprie
// 连接已关闭
Log("远程主机关闭了连接");
// 清理连接资源
CleanupConnectionResources(localStream, localTcpClient, out localStream, out localTcpClient);
continue;
lock (_lockObject)
{
if (_temperatureTcpClient != null)
{
_temperatureTcpClient.Close();
_temperatureTcpClient = null;
}
}
break;
}
}
}
@@ -1686,11 +1739,34 @@ namespace JoyD.Windows.CS.Toprie
// 温度数据接收状态更新代码已移除,因为未被使用
// 清理连接资源
CleanupConnectionResources(localStream, localTcpClient, out localStream, out localTcpClient);
lock (_lockObject)
{
if (_temperatureTcpClient != null)
{
_temperatureTcpClient.Close();
_temperatureTcpClient = null;
}
}
// 异常后等待一段时间再重试
Thread.Sleep(ERROR_SLEEP_MS);
}
finally
{
// 关闭网络流
if (localStream != null)
{
try
{
localStream.Close();
localStream = null;
}
catch (Exception ex)
{
Log($"关闭网络流异常: {ex.Message}");
}
}
}
}
}
}
@@ -1702,7 +1778,36 @@ namespace JoyD.Windows.CS.Toprie
// 温度数据接收状态更新代码已移除,因为未被使用
// 清理资源
CleanupConnectionResources(localStream, localTcpClient, out localStream, out localTcpClient);
// 关闭网络流
if (localStream != null)
{
try
{
localStream.Close();
localStream = null;
}
catch (Exception ex)
{
Log($"关闭网络流异常: {ex.Message}");
}
}
// 关闭TCP客户端
lock (_lockObject)
{
if (_temperatureTcpClient != null)
{
try
{
_temperatureTcpClient.Close();
_temperatureTcpClient = null;
}
catch (Exception ex)
{
Log($"关闭TCP客户端异常: {ex.Message}");
}
}
}
Log("温度数据接收线程已结束,重置相关状态");
}