using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Net.Sockets; using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; namespace DataCollectionSystem.CommonLib.IOCARD { public class ConnectStateEventArgs : EventArgs { Boolean bConnected = false; string Info = string.Empty; public ConnectStateEventArgs(Boolean bConnected,string Info) { this.bConnected = bConnected; this.Info = Info; } } public class IOCard { private Socket socket = null; private byte[] buffer = new byte[1024]; //字符串转16进制 public static byte[] hexStringToByteArray(string hexString) { hexString = hexString.Replace(" ", ""); if ((hexString.Length % 2) != 0) hexString += " "; byte[] returnBytes = new byte[hexString.Length / 2]; for (int i = 0; i < returnBytes.Length; i++) { try { returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16); } catch (System.FormatException) { } } return returnBytes; } //字节数组转换为十六进制字符串 public static string bytesToHex(byte[] bytes) { char[] hexChars = new char[bytes.Length * 2]; for (int j = 0; j < bytes.Length; j++) { int v = bytes[j] & 0xFF; hexChars[j * 2] = "0123456789ABCDEF".ToCharArray()[v >> 4]; hexChars[j * 2 + 1] = "0123456789ABCDEF".ToCharArray()[v & 0x0F]; } return new String(hexChars); } public static String CRCForModbus(String data) { //处理数字转换 String sendBuf = data; String sendnoNull1 = sendBuf.Trim();//去掉字符串前后的空格 String sendnoNull2 = sendnoNull1.Replace(" ", "");//去掉字符串中间的空格 String sendNOComma = sendnoNull2.Replace(',', ' '); //去掉英文逗号 String sendNOComma1 = sendNOComma.Replace(',', ' '); //去掉中文逗号 String strSendNoComma2 = sendNOComma1.Replace("0x", ""); //去掉0x data = strSendNoComma2.Replace("0X", ""); //去掉0X Byte[] crcbuf = hexStringToByteArray(data); //计算并填写CRC校验码 Int32 crc = 0xffff; Int32 len = crcbuf.Length; for (Int32 n = 0; n < len; n++) { Byte i; crc = crc ^ crcbuf[n]; for (i = 0; i < 8; i++) { Int32 TT; TT = crc & 1; crc = crc >> 1; crc = crc & 0x7fff; if (TT == 1) { crc = crc ^ 0xa001; } crc = crc & 0xffff; } } crc = ((crc & 0xFF) << 8 | (crc >> 8));//高低字节换位 String CRCString = crc.ToString("X2"); if (CRCString.Length % 2 != 0) { CRCString = "0" + CRCString; } return (data + CRCString); } public EventHandler EventConnect; private void DoEventConnect(Boolean bConnected,String Info) { EventConnect?.Invoke(this, new ConnectStateEventArgs(bConnected, Info)); } private void establish(String ip, ushort Port) { try { //①创建一个Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //②连接到指定服务器的指定端口 socket.Connect(ip, Port); //localhost代表本机 DoEventConnect(false,string.Empty) ; //③实现异步接受消息的方法 客户端不断监听消息 socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveMessage), socket); //④接受用户输入,将消息发送给服务器端 } catch (Exception ex) { /* this.BeginInvoke((EventHandler)(delegate { btn_connect.Text = "连接"; })); UIMessageTip.ShowError("client:error " + ex.Message); */ DoEventConnect(false, "client:error "+ex.Message); } } public void ReceiveMessage(IAsyncResult ar) { try { var socket = ar.AsyncState as Socket; //方法参考 var length = socket.EndReceive(ar); //读取出来消息内容 var message = Encoding.ASCII.GetString(buffer, 0, length); byte[] tem = new byte[length]; Array.Copy(buffer, 0, tem, 0, length); Array.Clear(buffer, 0, buffer.Length); //显示消息 //WriteLine(message, ConsoleColor.White); /* this.BeginInvoke((EventHandler)(delegate { // richTextBox1.Text = message; lb_read.Text = "设备已回复:" + bytesToHex(tem); })); */ //接收下一个消息(因为这是一个递归的调用,所以这样就可以一直接收消息了) socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveMessage), socket); } catch (Exception ex) { // MessageBox.Show(ex.Message); DoEventConnect(false, "client:error " + ex.Message); } } public void send(string HEXstring) { try { //发送数据 socket.BeginSend(hexStringToByteArray(HEXstring), 0, hexStringToByteArray(HEXstring).Length, SocketFlags.None, null, null); } catch (Exception ex) { // Debug.WriteLine(err); DoEventConnect(false, "client:error " + ex.Message); } } } }