using System; using System.Collections.Generic; using System.Linq; using System.Net.NetworkInformation; using System.Net; using System.Text; using System.Threading.Tasks; using System.Net.Sockets; using Newtonsoft.Json; using JinYuan.Models; using System.Buffers; using System.Threading; using Org.BouncyCastle.Ocsp; using HslCommunication.CNC.Fanuc; #region 命令行 //59 喷码机往外部系统发送的已喷印完成个数命令。 //60 是否开启发送已喷印完成个数命令,如果开启,喷码机每打印完一个或多个数据,就往外部系统发送一条已喷印完成个数命令,命令内容为已喷印完成个数。 //61 重置打印完成个数。 //62 读取设备唯一标识码。 //63 设置计划个数。 //64 是否开启发送打印完成内容命令,如果开启,喷码机每打印完一个或多个数据,就往外部系统发送一条打印完成数据命令,命令内容为喷印的内容。 //65 查询67号命令发送的未打印缓存数据个数。 //66 清空67号命令发送的缓存数据。 //67 修改标签内容,并将内容放置到缓存。 //68 查询已喷印完成个数。 //69 发送文件到喷码机 //70 创建新文档。 //71 设置喷印模式参数。 //72 喷码机往外部系统发送的打印完成内容命令。 //73 创建标签命令 //74 设置散喷状态 //82 修改标签内容。 //83 启动喷印。 //84 停止喷印。 //85 打开喷码机文档命令。 //86 发送图片到喷码机打印缓存 //87 查询喷码机状态 //88 喷码机向PC发送的报警信息 //89 开启、停止负压、清洗喷头、挤墨功能码 #endregion namespace JinYuan.Helper { public class JetClientHelper { public const int BufferSize = 1024;//6kb private int _timeout = 2000; private Ping _ping = null; private IPEndPoint _endPoint = null; private Socket JetClientSocket = null; private PingReply _pingReply = null; public bool connectState => Connected; /// /// 构造函数 /// public JetClientHelper() { // used to ping the PLC // this._ping = new Ping(); // EndPoint parametres // this._endPoint = new IPEndPoint(0, 0); } /// /// set ip and port /// public void SetTCPParams(IPAddress ip, int port) { this._endPoint.Address = ip; this._endPoint.Port = port; } /// /// returns the connection status /// public bool Connected { get { try { return (JetClientSocket == null) ? false : JetClientSocket.Connected; } catch (Exception ex) { //PrintfLog.LogError(ex.Message); return false; } } } /// /// close the socket /// /// public void Close() { lock (this) { if (JetClientSocket == null) return; if (Connected) { JetClientSocket.Disconnect(false); JetClientSocket.Close(); } JetClientSocket.Dispose(); JetClientSocket = null; } } /// /// 尝试多次连接喷码机,直到成功或达到最大重试次数 /// /// 最大重试次数(默认3次) /// 每次重试间隔毫秒(默认50ms) /// 是否最终连接成功 public bool ConnectWithRetry(int maxRetryCount = 6, int retryDelayMs = 50) { for (int attempt = 1; attempt <= maxRetryCount; attempt++) { if (this.Connect()) { // 可选:记录成功日志 //TxtHelper.WriteTxt($@"D:\APILog\Logs\喷码机信息\{DateTime.Now:yyyy-MM-dd}.txt", //$"{DateTime.Now:yyyy-MM-dd HH:mm:ss} 喷码机连接成功,尝试次数:{attempt}"); return true; } // 如果不是最后一次尝试,则等待 if (attempt < maxRetryCount) { Thread.Sleep(retryDelayMs); } } // 所有重试均失败 TxtHelper.WriteTxt($@"D:\APILog\Logs\喷码机信息\{DateTime.Now:yyyy-MM-dd}.txt", $"{DateTime.Now:yyyy-MM-dd HH:mm:ss} 喷码机连接失败,已重试{maxRetryCount}次"); return false; } public bool Connect() { try { if (Ping()) { if (this.TCPConnect()) { return true; } else { return false; } } else { return false; } } catch (Exception ex) { Close(); return false; } } private bool TCPConnect() { try { if (JetClientSocket != null) { JetClientSocket.Dispose(); } JetClientSocket = new Socket(_endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); JetClientSocket.SendTimeout = _timeout; JetClientSocket.ReceiveTimeout = _timeout; JetClientSocket.Connect(this._endPoint); return this.Connected; } catch (System.Exception ex) { return false; } } public bool Ping() { try { if (this._endPoint.Address == null) { return false; } this._pingReply = this._ping.Send(this._endPoint.Address, this._timeout); if (this._pingReply.Status == IPStatus.Success) { return true; } else { return false; } } catch (Exception) { //PrintfLog.LogError("ECFFU ping exception"); return false; } } public bool SendAndGetRes(string json, ref JetReturnResult jet) { var arrayPool = ArrayPool.Shared; byte[] RecvData = arrayPool.Rent(BufferSize);//new byte[1024]; int size = 1024; int receiveMax = 0; if (!Ping()) { return false; } try { // json转bytes[] byte[] bytes = Encoding.UTF8.GetBytes(json); //// 发送 //JetClientSocket.Send(bytes, bytes.Length, SocketFlags.None); //// 接收 //int response = 1024; //string js = ""; //while (JetClientSocket.Receive(buffer) != 0 && receiveMax < 3) //{ // js = Encoding.UTF8.GetString(buffer, 0, response); // Thread.Sleep(100); // receiveMax++; //} // 发送 Send(bytes, bytes.Length); // 接收 Receive(ref RecvData, size); // 解析 string js = string.Empty; js = Encoding.UTF8.GetString(RecvData, 0, RecvData.Length); // 找到第一个 { 和最后一个 } 的位置 int start = json.IndexOf('{'); int end = json.LastIndexOf('}'); //json反序列化 if (!string.IsNullOrEmpty(js)) { js = json.Substring(start, end - start + 1); jet = JsonConvert.DeserializeObject(js); // 处理二进制数据(如有需要) byte[] binaryData = Encoding.ASCII.GetBytes(json.Substring(end + 1)); } else { // 异常ref jet jet.KEY = ""; jet.DATA = jet.DATA; jet.RS = "TIMEOUT"; TxtHelper.WriteTxt($@"D:\APILog\Logs\喷码机信息\{DateTime.Now.ToString("yyyy-MM-dd")}.txt", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + $"喷码机数据收发超时,发送json:{json}"); } //JetClientSocket. //关闭socket //JetClientSocket.Shutdown(SocketShutdown.Both); //JetClientSocket.Close(); } catch (Exception ex) { TxtHelper.WriteTxt($@"D:\APILog\Logs\喷码机信息\{DateTime.Now.ToString("yyyy-MM-dd")}.txt", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + $"喷码机返回原始数据:{string.Join(" ", RecvData)}"); TxtHelper.WriteTxt($@"D:\APILog\Logs\喷码机信息\{DateTime.Now.ToString("yyyy-MM-dd")}.txt", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + $"喷码机数据收发异常,原因:{ex}"); // 异常ref jet jet.KEY = ""; jet.DATA = jet.DATA; jet.RS = "ERROR"; Close(); return false; } finally { arrayPool.Return(RecvData); } return true; } /// /// send a command to energy meter device /// /// /// /// private int Send(Byte[] command, int cmdLen) { if (!Connected) { throw new Exception("JetMachine Socket is not connected."); } // sends the command // int bytesSent = JetClientSocket.Send(command, cmdLen, SocketFlags.None); // it checks the number of bytes sent // if (bytesSent != cmdLen) { string msg = string.Format("JetMachine Sending error. (Expected bytes: {0} Sent: {1})", cmdLen, bytesSent); throw new Exception(msg); } return bytesSent; } /// /// receives a response from the plc /// /// /// /// private int Receive(ref Byte[] response, int respLen) { if (!this.Connected) { throw new Exception("JetMachine Socket is not connected."); } // receives the response, this is a synchronous method and can hang the process int bytesRecv = JetClientSocket.Receive(response, respLen, SocketFlags.None); // check the number of bytes received // // if (bytesRecv != respLen) // { // string msg = string.Format("Receiving error. (Expected: {0} Received: {1})" // , respLen, bytesRecv); // throw new Exception(msg); // } return bytesRecv; } } }