kazelee
21 小时以前 f8d23dcf8d6501482db1a5180325194232afe96c
device/TcpClientHelper.cs
@@ -26,15 +26,15 @@
        public static bool Init(string ip, int port) {
            lock (_connectLock) {
                try {
                    // 若正在连接中,直接返回
                    // 若正在连接中,直接返回
                    if (_isConnecting) {
                        LogHelper.Info("已有连接正在尝试中,禁止重复操作");
                        LogHelper.Info("已有连接正在尝试中,禁止重复操作");
                        return false;
                    }
                    _isConnecting = true; // 标记为连接中
                    // 释放旧 Socket(仅在未连接时)
                    // 释放旧 Socket (仅在未连接时)
                    if (_clientSocket != null && !_clientSocket.Connected) {
                        SafeCloseSocket();
                    }
@@ -52,7 +52,7 @@
                }
                catch (SocketException ex) {
                    _isConnecting = false;
                    LogHelper.Error($"初始化连接失败: {ex.Message}", ex);
                    LogHelper.InfoEx(ex);
                    return false;
                }
            }
@@ -64,7 +64,7 @@
            lock (_linkLock) {
                try {
                    // 若Socket存在但实际已断开,强制清理
                    // 若Socket存在但实际已断开,强制清理
                    if (_clientSocket != null && (_clientSocket.Poll(0, SelectMode.SelectRead) && _clientSocket.Available == 0)) {
                        SafeCloseSocket();
                    }
@@ -72,7 +72,7 @@
                    // 原有逻辑
                    if (_clientSocket != null && _clientSocket.Connected) {
                        //if (ip == _ip && port == _port) {
                            LogHelper.Info($"产线已连接,无需重连,IP:{ip},端口:{port}");
                            LogHelper.Info($"产线已连接,无需重连,IP:{ip},端口:{port}");
                            return false;
                        //}
@@ -82,7 +82,7 @@
                    return Init(ip, port);
                }
                catch (Exception ex) {
                    LogHelper.Error($"产线重连失败,IP:{ip},端口:{port},异常:{ex.Message}", ex);
                    LogHelper.InfoEx(ex);
                    return false;
                }
            }
@@ -134,11 +134,11 @@
                    // 仅在连接成功时启动接收
                    if (_clientSocket.Connected) {
                        LogHelper.Info($"成功连接到服务端:{_ip}:{_port}");
                        LogHelper.Info($"成功连接到服务端:{_ip}:{_port}");
                        _clientSocket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, ReceiveCallback, null);
                    }
                    else {
                        LogHelper.Info("连接未成功,关闭Socket");
                        LogHelper.Info("连接未成功,关闭Socket");
                        SafeCloseSocket();
                    }
                }
@@ -147,7 +147,7 @@
                LogHelper.Info("连接过程中Socket被释放");
            }
            catch (Exception ex) {
                LogHelper.Error($"连接失败:{ex.Message}", ex);
                LogHelper.InfoEx(ex);
                SafeCloseSocket();
            }
            finally {
@@ -166,16 +166,16 @@
                    _clientSocket.Close();
                    _clientSocket.Dispose();
                    // 断开后:清除对应IP:Port的接收数据
                    // 断开后:清除对应IP:Port的接收数据
                    string key = $"{_ip}:{_port}";
                    if (_receivedDataQueue.ContainsKey(key)) {
                        _receivedDataQueue.Remove(key);
                        LogHelper.Info($"已清理队列数据,Key:{key}");
                        LogHelper.Info($"已清理队列数据,Key:{key}");
                    }
                }
            }
            catch (Exception ex) {
                LogHelper.Error($"释放Socket资源异常:{ex.Message}", ex);
                LogHelper.InfoEx(ex);
            }
            finally {
                _clientSocket = null;
@@ -203,13 +203,13 @@
                    _clientSocket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, ReceiveCallback, null);
                }
                else {
                    // 服务端主动关闭连接,触发清理
                    // 服务端主动关闭连接,触发清理
                    LogHelper.Info("连接已被服务端关闭");
                    SafeCloseSocket();
                }
            }
            catch (Exception ex) {
                LogHelper.Error($"接收数据异常:{ex.Message}", ex);
                LogHelper.InfoEx(ex);
                SafeCloseSocket(); // 异常时主动关闭
            }
        }
@@ -229,19 +229,18 @@
                        //read = result;
                        return false;
                    }
                    LogHelper.Info($"读产线托盘下线数据成功:{BitConverter.ToString(result)}");
                    LogHelper.Info($"读产线托盘下线数据成功:{BitConverter.ToString(result)}");
                    read = result;
                    return true;
                }
                else {
                    //LogHelper.Info($"_clientSocket={_clientSocket} connected={_clientSocket?.Connected}");
                    Link(_ip, _port);
                    LogHelper.Info($"读产线托盘下线数据失败(未连接),准备重连");
                    LogHelper.Info($"读产线托盘下线数据失败 (未连接) ,准备重连");
                    return false;
                }
            }
            catch (Exception ex) {
                //LogHelper.Error($"读产线托盘下线数据失败(发生了异常:{JsonConvert.SerializeObject(ex)}):{ex.Message}", ex);
                LogHelper.InfoEx(ex);
                return false;
                /* 异常处理 */
@@ -256,11 +255,11 @@
        /// <param name="registers">Modbus寄存器数组</param>
        /// <returns>字节数组</returns>
        public static byte[] ConvertRegistersToBytes(ushort[] registers) {
            // 每个寄存器是16位(2字节),所以总字节数是寄存器数量的2倍
            // 每个寄存器是16位(2字节),所以总字节数是寄存器数量的2倍
            byte[] bytes = new byte[registers.Length * 2];
            for (int i = 0; i < registers.Length; i++) {
                // Modbus使用大端序,高位字节在前
                // Modbus使用大端序,高位字节在前
                bytes[i * 2] = (byte)(registers[i] >> 8);     // 高位字节
                bytes[i * 2 + 1] = (byte)(registers[i] & 0xFF); // 低位字节
            }
@@ -276,13 +275,13 @@
        public static string ConvertBytesToString(byte[] bytes) {
            // 查找第一个0x00字节(字符串结束符)的位置
            int length = Array.IndexOf(bytes, (byte)0);
            if (length < 0) length = bytes.Length; // 如果没有结束符,使用全部字节
            if (length < 0) length = bytes.Length; // 如果没有结束符,使用全部字节
            // 根据设备使用的编码转换(常见的有ASCII或UTF-8)
            // 这里使用ASCII编码作为示例,实际应根据设备文档确定编码方式
            // 这里使用ASCII编码作为示例,实际应根据设备文档确定编码方式
            return Encoding.ASCII.GetString(bytes, 0, length);
            // 如果是UTF-8编码,使用下面这行代替上面那行
            // 如果是UTF-8编码,使用下面这行代替上面那行
            // return Encoding.UTF8.GetString(bytes, 0, length);
        }
@@ -294,12 +293,12 @@
                }
                else {
                    Link(_ip, _port);
                    LogHelper.Info($"写电梯入货数据失败(未连接):{Encoding.UTF8.GetString(sends)}");
                    LogHelper.Info($"写电梯入货数据失败 (未连接) :{Encoding.UTF8.GetString(sends)}");
                    return false;
                }
            }
            catch (Exception ex) {
                LogHelper.Error($"写电梯入货数据失败(发送了异常):{ex.Message}", ex);
                LogHelper.InfoEx(ex);
                return false;
            }
        }
@@ -308,17 +307,17 @@
            try {
                if (_clientSocket != null && _clientSocket?.Connected == true) {
                    _receivedDataQueue.TryGetValue($"{_ip}:{_port}", out byte[] result);
                    LogHelper.Info($"读电梯出货数据成功:{BitConverter.ToString(result)}");
                    LogHelper.Info($"读电梯出货数据成功:{BitConverter.ToString(result)}");
                    return result;
                }
                else {
                    Link(_ip, _port);
                    LogHelper.Info($"读电梯出货数据失败(未连接),准备重连");
                    LogHelper.Info($"读电梯出货数据失败 (未连接) ,准备重连");
                    return null;
                }
            }
            catch (Exception ex) {
                LogHelper.Error($"读电梯出货数据失败(发生了异常:{JsonConvert.SerializeObject(ex)}):{ex.Message}", ex);
                LogHelper.InfoEx(ex);
                return null;
                /* 异常处理 */
            }
@@ -326,20 +325,20 @@
        public static string ChekElevator() {
            try {
                var res = "读取电梯数据的model,索引从1开始,满足以下条件才能发任务 \r\n " +
                   "字段,isNormal ,是否正常模式,1:正常模式,第7个Byte右侧第一位Bit \r\n" +
                   "字段,isValid,当前位置是否有效,1:有效,0:不用管,第9个Byte右侧第一位Bit \r\n" +
                   "字段,runMode,电梯运行模式,9=空闲泊停,7=自动运行,第10个Byte\r\n" +
                   "字段,isLock_1_Out,一层出口是否占用,1 = 占用,第14个Byte右侧第一位Bit\r\n" +
                   "字段,isLock_2_Out,二层出口是否占用,1 = 占用,第14个Byte右侧第二位Bit\r\n" +
                   "字段,taskNO,任务号\r\n" +
                   "判断电梯是否符合2楼到1楼搬送条件:isNormal  且 (runMode == 9 或 runMode == 7) 且 !isLock_1_Out \r\n" +
                   "判断电梯是否符合1楼到成品库区条件:isNormal  且 (runMode == 9 或 runMode == 7) 且 isLock_1_Out\r\n";
                var res = "读取电梯数据的model,索引从1开始,满足以下条件才能发任务 \r\n " +
                   "字段,isNormal ,是否正常模式,1:正常模式,第7个Byte右侧第一位Bit \r\n" +
                   "字段,isValid,当前位置是否有效,1:有效,0:不用管,第9个Byte右侧第一位Bit \r\n" +
                   "字段,runMode,电梯运行模式,9=空闲泊停,7=自动运行,第10个Byte\r\n" +
                   "字段,isLock_1_Out,一层出口是否占用,1 = 占用,第14个Byte右侧第一位Bit\r\n" +
                   "字段,isLock_2_Out,二层出口是否占用,1 = 占用,第14个Byte右侧第二位Bit\r\n" +
                   "字段,taskNO,任务号\r\n" +
                   "判断电梯是否符合2楼到1楼搬送条件:isNormal  且 (runMode == 9 或 runMode == 7) 且 !isLock_1_Out \r\n" +
                   "判断电梯是否符合1楼到成品库区条件:isNormal  且 (runMode == 9 或 runMode == 7) 且 isLock_1_Out\r\n";
                var isRead = ReadElevatorOutOk();
                var log = BitConverter.ToString(isRead);
                res += "读取到的电梯byte数组:" + log + "\r\n";
                res += "读取到的电梯byte数组:" + log + "\r\n";
                //if (isRead != null && isRead.Length >= 14) {
                //    var elevatorReadInfo = new ElevatorReadInfo() {
                //        isNormal = (isRead[6] & 1) == 1,
@@ -353,14 +352,14 @@
                //    var res1 = elevatorReadInfo.is2To1Ok();
                //    res += "判断电梯是否符合2楼到1楼搬送条件,如果符合则返回true,结果" + res1 + "\r\n";
                //    res += "判断电梯是否符合2楼到1楼搬送条件,如果符合则返回true,结果" + res1 + "\r\n";
                //    var res2 = elevatorReadInfo.is1ToOk();
                //    res += "判断电梯是否符合1楼到成品库区条件,如果符合则返回true,结果" + res2 + "\r\n";
                //    res += "判断电梯是否符合1楼到成品库区条件,如果符合则返回true,结果" + res2 + "\r\n";
                //}
                //else {
                //    return "读取电梯状态失败,byte数组要求大于等于14个且不为空";
                //    return "读取电梯状态失败,byte数组要求大于等于14个且不为空";
                //}
                return res;
            }
@@ -390,7 +389,7 @@
                return false;
            }
            catch (Exception ex) {
                LogHelper.Error($"判断电梯是否断电(发生了异常:{JsonConvert.SerializeObject(ex)}):{ex.Message}", ex);
                LogHelper.InfoEx(ex);
                return false;
            }
        }