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; /// /// 接收队列的上限 /// public int comDDLength = 100; /// /// 客户端的连接状态 /// 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; } } /// /// 清除缓存区中某条指令 /// /// /// public bool ClearMessage(int cmdID) { try { return true; } catch (Exception) { return false; } } /// /// 不启用监听功能时可以使用 /// /// 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); } } ///// ///// 启用监听功能时使用,默认接收队列中的第一个数据 ///// ///// 超时时间,单位ms ///// 返回接收到的数据 ///// //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; // } //} ///// ///// 异步接收信息,防止主线程卡死 ///// ///// ///// ///// //public Task ReceiveMsgAsync(double timeOut) //{ // return Task.Run(() => // { // ComData comData; // ReceiveMessage(timeOut, out comData); // return comData; // }); //} //// /// 结构体转byte数组 /// /// 要转换的结构体 /// 转换后的byte数组 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; } /// /// byte数组转结构体 /// /// byte数组 /// 结构体类型 /// 转换后的结构体 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; } } } } }