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;
}
}
}