2024-11-08 09:10:43 +08:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Concurrent;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Net.Sockets;
|
|
|
|
|
using System.Net;
|
|
|
|
|
using System.Runtime.InteropServices;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Threading;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using DocumentFormat.OpenXml.VariantTypes;
|
|
|
|
|
|
|
|
|
|
namespace LeatherApp.Device
|
|
|
|
|
{
|
|
|
|
|
public class DL_EN1Dev
|
|
|
|
|
{
|
|
|
|
|
TCPClient tCPClient;
|
|
|
|
|
|
|
|
|
|
public DL_EN1Dev()
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool startDev(string localIp, int port)
|
|
|
|
|
{
|
|
|
|
|
tCPClient = new TCPClient(localIp, port);
|
|
|
|
|
return tCPClient.TcpClientStart();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void stopDev()
|
|
|
|
|
{
|
|
|
|
|
tCPClient.CloseAll();
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-02 15:02:39 +08:00
|
|
|
|
public bool GetValue(out double val1, out double val2, out double val3)
|
2024-11-08 09:10:43 +08:00
|
|
|
|
{
|
2024-12-02 15:02:39 +08:00
|
|
|
|
val1 = val2 = val3 = 0;
|
2024-11-08 09:10:43 +08:00
|
|
|
|
bool ret = true;
|
|
|
|
|
string recv;
|
2024-12-02 15:02:39 +08:00
|
|
|
|
ret = tCPClient.SendMessage($"M0\r\n");
|
2024-11-08 09:10:43 +08:00
|
|
|
|
if ( !ret )
|
|
|
|
|
{
|
2024-12-02 15:02:39 +08:00
|
|
|
|
val1 = val2 = val3 = 7;
|
|
|
|
|
return false;
|
2024-11-08 09:10:43 +08:00
|
|
|
|
}
|
2024-12-02 15:02:39 +08:00
|
|
|
|
Thread.Sleep(20);
|
|
|
|
|
ret = tCPClient.ReceiveMessage(out recv);
|
2024-11-08 09:10:43 +08:00
|
|
|
|
if (!ret)
|
|
|
|
|
{
|
2024-12-02 15:02:39 +08:00
|
|
|
|
val1 = val2 = val3 = 8;
|
|
|
|
|
return false;
|
2024-11-08 09:10:43 +08:00
|
|
|
|
}
|
2024-12-02 15:02:39 +08:00
|
|
|
|
if (string.IsNullOrEmpty(recv))
|
2024-11-08 09:10:43 +08:00
|
|
|
|
{
|
2024-12-02 15:02:39 +08:00
|
|
|
|
val1 = val2 = val3 = 9;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var dataString = recv.Split(',');
|
|
|
|
|
ret = double.TryParse(dataString[1], out val1);
|
|
|
|
|
val1 = val1 / 1000;
|
|
|
|
|
ret = double.TryParse(dataString[2], out val2);
|
|
|
|
|
val2 = val2 / 1000;
|
|
|
|
|
ret = double.TryParse(dataString[3], out val3);
|
|
|
|
|
val3 = val3 / 1000;
|
|
|
|
|
}
|
|
|
|
|
catch {
|
|
|
|
|
val1 = val2 = val3 = -10;
|
|
|
|
|
return false;
|
2024-11-08 09:10:43 +08:00
|
|
|
|
}
|
2024-12-02 15:02:39 +08:00
|
|
|
|
return true;
|
2024-11-08 09:10:43 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//客户端类
|
|
|
|
|
public class TCPClient
|
|
|
|
|
{
|
|
|
|
|
//private TcpListener tcpListener = null;
|
|
|
|
|
private TcpClient tcpClient;
|
|
|
|
|
private IPAddress localIP;
|
|
|
|
|
private NetworkStream stream;
|
|
|
|
|
private int port;
|
|
|
|
|
//private int buffer_length = 0;
|
|
|
|
|
private bool isConnected;
|
|
|
|
|
Thread myThread = null;
|
|
|
|
|
CancellationTokenSource cts;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 接收队列的上限
|
|
|
|
|
/// </summary>
|
|
|
|
|
public int comDDLength = 100;
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 客户端的连接状态
|
|
|
|
|
/// </summary>
|
|
|
|
|
public bool IsConnected
|
|
|
|
|
{
|
|
|
|
|
get { return this.isConnected; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public TCPClient(string localIp, int port)
|
|
|
|
|
{
|
|
|
|
|
this.localIP = IPAddress.Parse(localIp);
|
|
|
|
|
this.port = port;
|
|
|
|
|
//this.buffer_length = Marshal.SizeOf(dataType);
|
|
|
|
|
}
|
|
|
|
|
public bool TcpClientStart()
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
tcpClient = new TcpClient();
|
|
|
|
|
tcpClient.Connect(this.localIP, this.port);
|
|
|
|
|
|
|
|
|
|
this.isConnected = true;
|
|
|
|
|
|
|
|
|
|
//ThreadStart myThreadDelegate = new ThreadStart(Listening);
|
|
|
|
|
////实例化新线程
|
|
|
|
|
//cts = new CancellationTokenSource();
|
|
|
|
|
//myThread = new Thread(myThreadDelegate);
|
|
|
|
|
//myThread.IsBackground = true;
|
|
|
|
|
//myThread.Start();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
catch (Exception)
|
|
|
|
|
{
|
|
|
|
|
this.isConnected = false;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
private void Listening()
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
while (true)
|
|
|
|
|
{
|
|
|
|
|
// 获取一个数据流对象来进行读取和写入
|
|
|
|
|
this.stream = tcpClient.GetStream();
|
|
|
|
|
if (this.stream.CanRead)
|
|
|
|
|
{
|
|
|
|
|
if (cts.Token.IsCancellationRequested) return;
|
|
|
|
|
byte[] buffer = new byte[256];//new byte[buffer_length];
|
|
|
|
|
int bytesLength = this.stream.Read(buffer, 0, buffer.Length);
|
|
|
|
|
#region 异常情况,服务器突然关闭
|
|
|
|
|
if (bytesLength == 0)
|
|
|
|
|
{
|
|
|
|
|
CloseAll();
|
|
|
|
|
this.isConnected = false;
|
|
|
|
|
//Thread.Sleep(500);
|
|
|
|
|
|
|
|
|
|
//while (true)
|
|
|
|
|
//{
|
|
|
|
|
// try
|
|
|
|
|
// {
|
|
|
|
|
// TcpClientStart();
|
|
|
|
|
// break;
|
|
|
|
|
// }
|
|
|
|
|
// catch (Exception)
|
|
|
|
|
// {
|
|
|
|
|
// }
|
|
|
|
|
//}
|
|
|
|
|
//break;
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
//object msg = BytesToStuct(buffer, this.type);
|
|
|
|
|
//if (msg == null) continue;
|
|
|
|
|
//lock (this)
|
|
|
|
|
//{
|
|
|
|
|
|
|
|
|
|
//}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (System.IO.IOException)//服务器异常断开
|
|
|
|
|
{
|
|
|
|
|
CloseAll();
|
|
|
|
|
this.isConnected = false;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
catch (Exception)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
public bool SendMessage(object sendMsg)
|
|
|
|
|
{
|
|
|
|
|
//把成 ASCII 字符串转化数据字符。
|
|
|
|
|
byte[] sendMsgbyte = null;
|
|
|
|
|
// NetworkStream stream = null;
|
|
|
|
|
//TcpClient tcpClient = new TcpClient();
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
//tcpClient.Connect(this.localIP, port);
|
|
|
|
|
this.stream = this.tcpClient.GetStream();
|
|
|
|
|
if (this.stream.CanWrite)
|
|
|
|
|
{
|
|
|
|
|
sendMsgbyte = StructToBytes(sendMsg);
|
|
|
|
|
stream.Write(sendMsgbyte, 0, sendMsgbyte.Length);
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
catch (Exception)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
public bool SendMessage(string sendMsg)
|
|
|
|
|
{
|
|
|
|
|
//把成 ASCII 字符串转化数据字符。
|
|
|
|
|
byte[] sendMsgbyte = null;
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
this.stream = this.tcpClient.GetStream();
|
|
|
|
|
if (this.stream.CanWrite)
|
|
|
|
|
{
|
|
|
|
|
sendMsgbyte = System.Text.Encoding.ASCII.GetBytes(sendMsg);
|
|
|
|
|
stream.Write(sendMsgbyte, 0, sendMsgbyte.Length);
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
catch (Exception)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 清除缓存区中某条指令
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="cmdID"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public bool ClearMessage(int cmdID)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
catch (Exception)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 不启用监听功能时可以使用
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="receiveMsg"></param>
|
|
|
|
|
public bool ReceiveMessage(out string receiveMsg)
|
|
|
|
|
{
|
|
|
|
|
receiveMsg = "";
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
// 获取一个数据流对象来进行读取和写入
|
|
|
|
|
stream = tcpClient.GetStream();
|
|
|
|
|
if (this.stream.CanRead)
|
|
|
|
|
{
|
|
|
|
|
byte[] buffer = new byte[this.tcpClient.ReceiveBufferSize];
|
|
|
|
|
this.stream.Read(buffer, 0, this.tcpClient.ReceiveBufferSize);
|
|
|
|
|
receiveMsg = Encoding.Default.GetString(buffer);
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
catch (SocketException)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
//MessageBox.Show(se.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
///// <summary>
|
|
|
|
|
///// 启用监听功能时使用,默认接收队列中的第一个数据
|
|
|
|
|
///// </summary>
|
|
|
|
|
///// <param name="timeOut">超时时间,单位ms</param>
|
|
|
|
|
///// <param name="comData">返回接收到的数据</param>
|
|
|
|
|
///// <returns></returns>
|
|
|
|
|
//public bool ReceiveMessage(double timeOut, out ComData comData)
|
|
|
|
|
//{
|
|
|
|
|
// comData = new ComData(0);
|
|
|
|
|
// try
|
|
|
|
|
// {
|
|
|
|
|
// DateTime startTime = DateTime.Now;
|
|
|
|
|
// while (true)
|
|
|
|
|
// {
|
|
|
|
|
// if (DateTime.Now.Subtract(startTime).TotalMilliseconds > timeOut)
|
|
|
|
|
// return false;
|
|
|
|
|
// if (comDataDic.Count > 0)
|
|
|
|
|
// {
|
|
|
|
|
// foreach (var item in comDataDic.Values)
|
|
|
|
|
// {
|
|
|
|
|
// if (comDataDic.TryRemove(item.cmdID, out comData))
|
|
|
|
|
// {
|
|
|
|
|
// comData.status = 1;
|
|
|
|
|
// return true;
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// catch (Exception)
|
|
|
|
|
// {
|
|
|
|
|
// return false;
|
|
|
|
|
// }
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
///// <summary>
|
|
|
|
|
///// 异步接收信息,防止主线程卡死
|
|
|
|
|
///// </summary>
|
|
|
|
|
///// <param name="cmdID"></param>
|
|
|
|
|
///// <param name="timeOut"></param>
|
|
|
|
|
///// <returns></returns>
|
|
|
|
|
//public Task<ComData> ReceiveMsgAsync(double timeOut)
|
|
|
|
|
//{
|
|
|
|
|
// return Task.Run(() =>
|
|
|
|
|
// {
|
|
|
|
|
// ComData comData;
|
|
|
|
|
// ReceiveMessage(timeOut, out comData);
|
|
|
|
|
// return comData;
|
|
|
|
|
// });
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
//// <summary>
|
|
|
|
|
|
|
|
|
|
/// 结构体转byte数组
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="structObj">要转换的结构体</param>
|
|
|
|
|
/// <returns>转换后的byte数组</returns>
|
|
|
|
|
public static byte[] StructToBytes(object structObj)
|
|
|
|
|
{
|
|
|
|
|
//得到结构体的大小
|
|
|
|
|
int size = Marshal.SizeOf(structObj);
|
|
|
|
|
//创建byte数组
|
|
|
|
|
byte[] bytes = new byte[size];
|
|
|
|
|
//分配结构体大小的内存空间
|
|
|
|
|
IntPtr structPtr = Marshal.AllocHGlobal(size);
|
|
|
|
|
//将结构体拷到分配好的内存空间
|
|
|
|
|
Marshal.StructureToPtr(structObj, structPtr, false);
|
|
|
|
|
//从内存空间拷到byte数组
|
|
|
|
|
Marshal.Copy(structPtr, bytes, 0, size);
|
|
|
|
|
//释放内存空间
|
|
|
|
|
Marshal.FreeHGlobal(structPtr);
|
|
|
|
|
//返回byte数组
|
|
|
|
|
return bytes;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// byte数组转结构体
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="bytes">byte数组</param>
|
|
|
|
|
/// <param name="type">结构体类型</param>
|
|
|
|
|
/// <returns>转换后的结构体</returns>
|
|
|
|
|
public static object BytesToStuct(byte[] bytes, Type type)
|
|
|
|
|
{
|
|
|
|
|
//得到结构体的大小
|
|
|
|
|
int size = Marshal.SizeOf(type);
|
|
|
|
|
//byte数组长度小于结构体的大小
|
|
|
|
|
if (size > bytes.Length)
|
|
|
|
|
{
|
|
|
|
|
//返回空
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
//分配结构体大小的内存空间
|
|
|
|
|
IntPtr structPtr = Marshal.AllocHGlobal(size);
|
|
|
|
|
//将byte数组拷到分配好的内存空间
|
|
|
|
|
Marshal.Copy(bytes, 0, structPtr, size);
|
|
|
|
|
//将内存空间转换为目标结构体
|
|
|
|
|
object obj = Marshal.PtrToStructure(structPtr, type);
|
|
|
|
|
//释放内存空间
|
|
|
|
|
Marshal.FreeHGlobal(structPtr);
|
|
|
|
|
//返回结构体
|
|
|
|
|
return obj;
|
|
|
|
|
}
|
|
|
|
|
public void CloseAll()
|
|
|
|
|
{
|
|
|
|
|
this.CloseResource();
|
|
|
|
|
}
|
|
|
|
|
private void CloseResource()
|
|
|
|
|
{
|
|
|
|
|
if (this != null)
|
|
|
|
|
{
|
|
|
|
|
cts.Cancel();
|
|
|
|
|
if (this.stream != null)
|
|
|
|
|
{
|
|
|
|
|
this.stream.Close();
|
|
|
|
|
this.stream.Dispose();
|
|
|
|
|
}
|
|
|
|
|
if (this.tcpClient != null)
|
|
|
|
|
{
|
|
|
|
|
this.tcpClient.Close();
|
|
|
|
|
this.tcpClient = null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|