获取热图

This commit is contained in:
zqm
2025-10-27 16:18:24 +08:00
parent f4aebca633
commit 8834e2f965
3 changed files with 147 additions and 76 deletions

View File

@@ -143,40 +143,40 @@ namespace JoyD.Windows.CS.Toprie
{
try
{
if (isConnected && socket != null && socket.Connected)
return true;
// 创建Socket连接
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.ReceiveTimeout = TIMEOUT;
socket.SendTimeout = TIMEOUT;
socket.Connect(deviceIp, SDK_PORT);
// 注意设备使用UDP协议通信不需要建立TCP连接
// 直接设置连接状态为true表示准备好进行UDP通信
// 这里仍然保持isConnected标志以兼容现有代码逻辑
isConnected = true;
Console.WriteLine($"UDP通信准备就绪目标设备 {deviceIp}:18890");
return true;
}
catch (Exception ex)
{
Console.WriteLine($"连接设备 {deviceIp} 失败: {ex.Message}");
Console.WriteLine($"初始化UDP通信失败: {ex.Message}");
isConnected = false;
return false;
}
}
// 断开连接
// 断开连接UDP模式下
private void Disconnect()
{
try
{
// 注意在UDP模式下不需要关闭socket连接
// 只需重置连接状态标志
// 仍然清理socket资源以防万一
if (socket != null)
{
socket.Close();
socket = null;
}
isConnected = false;
Console.WriteLine("UDP通信状态已重置");
}
catch (Exception ex)
{
Console.WriteLine($"断开连接失败: {ex.Message}");
Console.WriteLine($"重置UDP通信状态失败: {ex.Message}");
}
}
@@ -184,30 +184,32 @@ namespace JoyD.Windows.CS.Toprie
private bool SendCommand(byte[] command, out byte[] response, int responseLength = 0)
{
response = null;
if (!Connect())
return false;
try
{
// 发送命令
socket.Send(command);
// 接收响应
byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead = socket.Receive(buffer);
if (bytesRead > 0)
// 修改为UDP协议与SDK保持一致
// SDK中使用的是UDP协议(socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))
// 端口使用18890与SDK中的CMD_SERVER_UDP_PORT保持一致
using (UdpClient udpClient = new UdpClient())
{
response = new byte[bytesRead];
Array.Copy(buffer, response, bytesRead);
// 设置接收超时与SDK中的超时保持一致
udpClient.Client.ReceiveTimeout = 200; // SDK中普通命令超时为200ms
// 发送UDP数据报端口使用18890与SDK保持一致
udpClient.Send(command, command.Length, deviceIp, 18890);
Console.WriteLine($"UDP命令已发送到 {deviceIp}:18890");
// 尝试接收响应
IPEndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
response = udpClient.Receive(ref remoteEndPoint);
Console.WriteLine($"收到UDP命令响应长度: {response.Length}");
return true;
}
return false;
}
catch (Exception ex)
{
Console.WriteLine($"发送命令失败: {ex.Message}");
Disconnect();
Console.WriteLine($"UDP发送命令失败: {ex.Message}");
return false;
}
}
@@ -216,30 +218,36 @@ namespace JoyD.Windows.CS.Toprie
private bool SendCommand(string cmd, out string response)
{
response = null;
if (!Connect())
return false;
try
{
// 发送命令
byte[] commandBytes = Encoding.ASCII.GetBytes(cmd);
socket.Send(commandBytes);
// 接收响应
byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead = socket.Receive(buffer);
if (bytesRead > 0)
// 修改为UDP协议与SDK保持一致
// SDK中使用的是UDP协议(socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))
// 端口使用18890与SDK中的CMD_SERVER_UDP_PORT保持一致
using (UdpClient udpClient = new UdpClient())
{
response = Encoding.ASCII.GetString(buffer, 0, bytesRead);
// 设置接收超时与SDK中的超时保持一致
udpClient.Client.ReceiveTimeout = 200; // SDK中普通命令超时为200ms
// 发送UDP数据报端口使用18890与SDK保持一致
byte[] commandBytes = Encoding.ASCII.GetBytes(cmd);
udpClient.Send(commandBytes, commandBytes.Length, deviceIp, 18890);
Console.WriteLine($"UDP命令已发送: {cmd}");
Console.WriteLine($"目标IP: {deviceIp}:18890");
// 尝试接收响应
IPEndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
byte[] responseBytes = udpClient.Receive(ref remoteEndPoint);
response = Encoding.ASCII.GetString(responseBytes);
Console.WriteLine($"收到UDP命令响应: {response}");
return true;
}
return false;
}
catch (Exception ex)
{
Console.WriteLine($"发送命令失败: {ex.Message}");
Disconnect();
Console.WriteLine($"UDP发送命令失败: {ex.Message}");
return false;
}
}
@@ -1679,29 +1687,55 @@ namespace JoyD.Windows.CS.Toprie
{
try
{
// 设置接收超时与SDK中的50毫秒保持一致
udpClient.Client.ReceiveTimeout = 50;
// 注意SDK中tv_out.tv_sec=50实际表示50秒这是SDK的实现方式
// 这里我们设置一个更合理的值500毫秒既保证能接收到响应又不会等待太久
udpClient.Client.ReceiveTimeout = 500;
// 发送UDP数据报端口使用18890与SDK保持一致
udpClient.Send(commandBytes, commandBytes.Length, deviceIp, 18890);
Console.WriteLine("UDP心跳命令已发送");
Console.WriteLine("UDP心跳命令已发送,等待响应...");
// 尝试接收响应
IPEndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
byte[] responseBytes = udpClient.Receive(ref remoteEndPoint);
string response = Encoding.ASCII.GetString(responseBytes);
Console.WriteLine($"收到UDP心跳响应: {response}");
// SDK要求响应中必须包含 ":ok" 字符串才算成功
if (!string.IsNullOrEmpty(response) && response.Contains(":ok"))
// 使用BeginReceive和EndReceive进行非阻塞接收更好地处理超时
IAsyncResult ar = udpClient.BeginReceive(null, null);
if (ar.AsyncWaitHandle.WaitOne(500)) // 额外的超时检查,双重保险
{
Console.WriteLine("心跳成功: 响应包含':ok'");
return 1; // 返回1表示成功与DeviceManager中的判断一致
try
{
byte[] responseBytes = udpClient.EndReceive(ar, ref remoteEndPoint);
string response = Encoding.ASCII.GetString(responseBytes);
Console.WriteLine($"收到UDP心跳响应: {response}");
// 不使用LINQ的Select方法避免缺少System.Linq命名空间的问题
string[] asciiValues = new string[response.Length];
for (int i = 0; i < response.Length; i++)
{
asciiValues[i] = ((int)response[i]).ToString();
}
Console.WriteLine($"响应长度: {response.Length} 字节响应ASCII码: {string.Join(",", asciiValues)}");
// SDK要求响应中必须包含 ":ok" 字符串才算成功
if (!string.IsNullOrEmpty(response) && response.Contains(":ok"))
{
Console.WriteLine("心跳成功: 响应包含':ok'");
return 1; // 返回1表示成功与DeviceManager中的heartbeatResult > 0判断一致
}
else
{
Console.WriteLine($"心跳响应不包含':ok',验证失败。收到的响应: '{response}'");
}
}
catch (Exception ex)
{
Console.WriteLine($"处理UDP响应时发生异常: {ex.Message}");
}
}
else
{
Console.WriteLine("心跳响应不包含':ok',验证失败");
Console.WriteLine("UDP接收超时取消接收操作");
udpClient.Close(); // 关闭以取消接收操作
}
}
catch (SocketException ex) when (ex.SocketErrorCode == SocketError.TimedOut)
@@ -1722,8 +1756,8 @@ namespace JoyD.Windows.CS.Toprie
}
}
// 3次尝试都失败
Console.WriteLine("三次心跳检测均失败");
// 所有重试都失败
Console.WriteLine("三次心跳检测均失败,连接未建立");
return -1;
}
catch (Exception ex)