397 lines
13 KiB
C#
397 lines
13 KiB
C#
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();
|
||
}
|
||
|
||
public bool GetValue(out double val1, out double val2, out double val3)
|
||
{
|
||
val1 = val2 = val3 = 0;
|
||
bool ret = true;
|
||
string recv;
|
||
ret = tCPClient.SendMessage($"M0\r\n");
|
||
if ( !ret )
|
||
{
|
||
val1 = val2 = val3 = 7;
|
||
return false;
|
||
}
|
||
Thread.Sleep(20);
|
||
ret = tCPClient.ReceiveMessage(out recv);
|
||
if (!ret)
|
||
{
|
||
val1 = val2 = val3 = 8;
|
||
return false;
|
||
}
|
||
if (string.IsNullOrEmpty(recv))
|
||
{
|
||
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;
|
||
}
|
||
return true;
|
||
}
|
||
}
|
||
|
||
//客户端类
|
||
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;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|