client类
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 using System.Net.Sockets; 7 using System.Threading; 8 using System.Net; 9 using System.Windows.Forms; 11 namespace SocketClientTest 12 { 13 public class SocketClient 14 { 15 public event Action<string> EventReceive; 16 public event Func< string,bool > EventSend; 17 public event Action<string> EventconnectState; //1:链接 0:断开 18 public Socket NewScocket = null; 19 byte[] byteBuffer = new byte[512]; 20 string beginMsg = string.Empty; 21 public int isconnect = 0; //0未连接 1成功 2连接失败 3plc断开 22 //string endMsg = " "; 23 Log log = new Log(); 24 public SocketClient() 25 { 26 EventSend += Send; 27 28 System.Windows.Forms.Timer nTime = new System.Windows.Forms.Timer(); 29 nTime.Interval = 500; 30 nTime.Tick += NTime_Tick; 31 nTime.Enabled = true; 32 } 33 34 private void NTime_Tick(object sender, EventArgs e) 35 { 36 if (NewScocket!=null&& NewScocket.Connected) 37 { 38 if (EventconnectState != null) 39 { 40 EventconnectState("1"); 41 } 42 } 43 else 44 { 45 if (EventconnectState != null) 46 { 47 EventconnectState("0"); 48 } 49 } 50 } 51 52 public bool Connect(string ip,int port) 53 { 54 try 55 { 56 if (NewScocket != null && NewScocket.Connected) //只有一个client 57 { 58 Close(NewScocket); 59 } 60 NewScocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 61 NewScocket.Blocking = false; 62 IPEndPoint ipe = new IPEndPoint(IPAddress.Parse(ip), port); 63 //绑定 异步链接 64 NewScocket.BeginConnect(ipe, new AsyncCallback(OnConnectRequest), NewScocket); 65 return true; 66 } 67 catch (Exception) 68 { 69 log.WriteLog("链接异常"); 70 MessageBox.Show("链接异常", "链接提示"); 71 return false; 72 } 73 } 74 75 private void OnConnectRequest(IAsyncResult ar) 76 { 77 //获取链接状态 78 Socket _Socket = (Socket)ar.AsyncState;// 79 try 80 { 81 //判断链接是否成功 82 if (_Socket.Connected) 83 { 84 SetReceiveCallback(_Socket); 85 // MessageBox.Show("链接成功"); 86 //log.WriteLog("链接成功"); 87 isconnect = 1; 88 //if (EventconnectState!=null) 89 //{ 90 // EventconnectState("1"); 91 //} 92 } 93 else 94 { 95 log.WriteLog("链接失败,请检查网线"); 96 MessageBox.Show("链接失败,请检查网线", "链接提示"); 97 isconnect = 2; 98 99 } 100 } 101 catch (Exception) 102 { 103 log.WriteLog("链接异常"); 104 MessageBox.Show("链接异常", "链接提示"); 105 isconnect = 2; 106 107 } 108 } 109 110 /// <summary> 111 /// 回调法法 112 /// </summary> 113 private void SetReceiveCallback(Socket _Sock) 114 { 115 AsyncCallback receive = new AsyncCallback(OnReceiveData); 116 _Sock.BeginReceive(byteBuffer, 0, byteBuffer.Length, SocketFlags.None, OnReceiveData, _Sock); 117 } 118 119 /// <summary> 120 /// 接受数据 121 /// </summary> 122 /// <param name="ar"></param> 123 private void OnReceiveData(IAsyncResult ar) 124 { 125 Socket _Sock = (Socket)ar.AsyncState; 126 try 127 { 128 int receiveLengthData = _Sock.EndReceive(ar); 129 //大于0接受到报文数据 130 if (receiveLengthData > 0) 131 { 132 // if (m_ByteBuffer[0]==0) 133 //接受到的数据 134 string receiveMsg = Encoding.UTF8.GetString(byteBuffer, 0, receiveLengthData); 135 //传值 136 if (EventReceive!=null) 137 { 138 EventReceive(receiveMsg); 139 } 140 //重复调用 141 SetReceiveCallback(_Sock); 142 } 143 else 144 { 145 //光闭Socket 146 MessageBox.Show("plc已关闭"); 147 isconnect = 3; 148 Close(_Sock); 149 } 150 } 151 catch (Exception ) 152 { 153 } 154 } 155 156 /// <summary> 157 /// 发送数据 158 /// </summary> 159 public bool Send(string str)//字符串转字节发送 160 { 161 //把字符转换字节 162 byte[] _ByteSend = Encoding.UTF8.GetBytes(str); 163 //发送数据 164 try 165 { 166 NewScocket.Send(_ByteSend, _ByteSend.Length, 0); 167 //if (EventReceive != null) 168 //{ 169 // EventReceive.Invoke("客户端:"+str); 170 //} 171 return true; 172 } 173 catch (Exception) 174 { 175 return false; 176 } 177 178 } 179 180 181 public bool strToHexByte(string hexString)//字符串转成16进制发送 182 { 183 184 hexString = hexString.Replace(" ", ""); 185 if ((hexString.Length % 2) != 0) 186 hexString += " "; 187 byte[] returnBytes = new byte[hexString.Length / 2]; 188 for (int i = 0; i < returnBytes.Length; i++) 189 //转字节发送 190 returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2).Replace(" ", ""), 10);//十进制 191 192 //转字发送 193 byte[] bytes = new byte[12]; 194 // UInt16 a = 54543; 195 for (int j = 0; j < returnBytes.Length; j++) 196 { 197 byte[] tempbyte = new byte[2]; 198 tempbyte = BitConverter.GetBytes(returnBytes[j]); 199 bytes[j * 2] = tempbyte[1]; 200 bytes[j * 2 + 1] = tempbyte[0]; 201 } 202 try 203 { 204 NewScocket.Send(bytes, bytes.Length, 0); 205 //if (EventReceive != null)//客户端发送后单纯的只是为了显示再客户端的界面上而已 206 //{ 207 // EventReceive.Invoke("客户端:" + hexString);//客户端发送的数据 208 // //EventReceive.Invoke(hexString); 209 //} 210 return true; 211 } 212 catch (Exception) 213 { 214 return false; 215 } 216 } 217 218 public bool SendDM(string str)//字符串转字节发送 219 { 220 //把字符转换字节 221 byte[] _ByteSend = Encoding.ASCII.GetBytes(str); 222 //发送数据 223 try 224 { 225 NewScocket.Send(_ByteSend, _ByteSend.Length, 0); 226 //if (EventReceive != null) 227 //{ 228 // EventReceive.Invoke("客户端:"+str); 229 //} 230 return true; 231 } 232 catch (Exception) 233 { 234 return false; 235 } 236 237 } 238 239 /// <summary> 240 /// 关闭Sockte 241 /// </summary> 242 /// <param name="sockte"></param> 243 public void Close(Socket socket) 244 { 245 if(socket != null&& socket.Connected) 246 { 247 socket.Shutdown(SocketShutdown.Both); 248 Thread.Sleep(10); 249 socket.Close(); 250 } 251 } 252 } 253 }
Form1.C
1 //全局变量
SocketClient ks = new SocketClient(); //一个通讯 2 SocketClient keep_heart = new SocketClient(); //一个发送心跳包 3 string ip = "127.0.0.1"; 4 int port = 9000; 5 int heart_port = 8501; 6 private void Form1_Load(object sender, EventArgs e) 7 {
ks.EventReceive += ReceiveText; 8 Thread thread1 = new Thread(() => //发送心跳 9 { 10 int i = 0; 11 while (true) 12 { 13 if (keep_heart.NewScocket!=null&&keep_heart.NewScocket.Connected) 14 { 15 string RD = null; 16 if (i % 2 == 0) 17 { 18 RD = "WR MR" + "9100" + ".L " + "0" + " ";//注意".L "中是有空格的 19 } 20 else 21 { 22 RD = "WR MR" + "9100" + ".L " + "1" + " ";//注意".L "中是有空格的 23 } 24 keep_heart.SendDM(RD); 25 } 26 i++; 27 Thread.Sleep(500); 28 } 29 }); 30 thread1.Start(); 31 Thread judge_state = new Thread(() => //判断是否关闭 32 { 33 while (true) 34 { 35 if (ks.isconnect == 3) 36 { 37 this.BeginInvoke(new MethodInvoker(() => 38 { 39 textBox3.Text = "断开"; 40 textBox3.BackColor = Color.Yellow; 41 btn_start.Enabled = true; 42 })); 43 ks.Close(ks.NewScocket); 44 keep_heart.Close(keep_heart.NewScocket); 45 display_log("plc已断开"); 46 } 47 Thread.Sleep(500); 48 } 49 50 }); 51 judge_state.Start(); 52 judge_state.IsBackground = true; 53 } 54 private void btn_start_Click(object sender, EventArgs e) 55 { 56 if (stastuLine)//在线模式 57 { //连接PLC 69 ks.Connect(ip, port); 70 while(ks.isconnect==0||ks.isconnect==3) 71 { 72 Thread.Sleep(50); 73 } 74 if (ks.isconnect == 1) 75 { 76 lab_plcStatu.Text = "在线"; 77 lab_plcStatu.ForeColor = Color.Green; 78 textBox3.Text = "连接"; 79 textBox3.BackColor = Color.Green; 80 81 MessageBox.Show("连接PLC成功", "温馨提示"); 82 display_log("plc连接成功"); 83 btn_start.Enabled = false; 84 ks.isconnect = 0; 85 86 //plc链接成功后,再判断心跳 87 keep_heart.Connect(ip, heart_port); 88 while(keep_heart.isconnect==0||keep_heart.isconnect==3) 89 { 90 Thread.Sleep(50); 91 } 92 if (keep_heart.isconnect == 1) 93 { 94 display_log("plc心跳连接成功"); 95 keep_heart.isconnect = 0; 96 97 } 98 else if (keep_heart.isconnect == 2) 99 { 100 display_log("plc心跳连接失败"); 101 MessageBox.Show("plc心跳连接失败", "温馨提示"); 102 } 103 104 } 105 else if(ks.isconnect == 2) 106 { 107 lab_plcStatu.Text = "离线"; 108 lab_plcStatu.ForeColor = Color.Black; 109 textBox3.Text = "断开"; 110 textBox3.BackColor = Color.Yellow; 111 log.WriteLog("连接PLC失败"); 112 display_log("连接plc失败"); 113 MessageBox.Show("连接PLC失败", "温馨提示"); 114 ks.isconnect = 0; 115 } 116 #endregion 117 } 118 } 119 138 139 public void ReceiveText(string s)//接收函数 140 { 141 142 if (s == "1111")//如果收到1111信号,进行处理 143 { 144 145 } 146 if (ks.Send(“”))//发送数据 147 { 148 } 149 else 150 { 151 } 152 153 }