using System; using System.Collections.Generic; using System. Linq; using System.Net.NetworkInformation; using System.Net.Sockets; using System.Net; using System. Text; using System. Threading; using System. Threading. Tasks; using System.Collections.Concurrent; using System. Drawing; namespace TorqueCollect { class AsyncTcpClient { private string ip; private string detail filename; private int port; public byte Delimiter = 0x00; // NUL accepts information delimiter private bool IsClose = false; //singleton private TcpClient tcpClient; //connect to the server public void ConnectServer(string_ip, int_port) { ip = _ip; port = _port; detailfilename = ip.Replace(".", "_"); try { if (tcpClient != null) { tcpClient. Close(); } tcpClient = new TcpClient(); Task.Factory.StartNew(() => ReCon(), TaskCreationOptions.LongRunning); Task.Factory.StartNew(() => PingOC(), TaskCreationOptions.LongRunning); Task.Factory.StartNew(() => ReceivedData(), TaskCreationOptions.LongRunning); } catch (Exception e) { } } private void ReCon() { while (!IsClose) { try { if (tcpClient.Client != null & & tcpClient.Connected) { SetCon(1); } else { //SetCon(-1); SetCon(0); //Disconnect and reconnect tcpClient. Close(); tcpClient = new TcpClient(); //Asynchronous connection, there is a connection timeout tcpClient.ConnectAsync(ip, port).Wait(2000); //tcpClient.Connect(ip, port); } } catch (Exception ex) { Form1.mt.Show(ex.Message, true, detailfilename); } Thread. Sleep(1000); } } private List<byte>_queuedMsg = new List<byte>(); private void ReceivedData() { while (!IsClose) { try { if (tcpClient == null || tcpClient.Client == null || tcpClient.Connected == false || tcpClient.Available == 0) { Thread. Sleep(100); continue; } List<byte> bytesReceived = new List<byte>(); while (tcpClient. Available > 0 & & tcpClient.Connected) { byte[] nextByte = new byte[1]; tcpClient.Client.Receive(nextByte, 0, 1, SocketFlags.None); if (nextByte[0] == Delimiter) { byte[] msg = _queuedMsg.ToArray(); string Rcmsg = Encoding.ASCII.GetString(msg.ToArray()); _queuedMsg. Clear(); MyEventArgs e = new MyEventArgs(ip, Rcmsg); _MsgChange(e); } else { _queuedMsg.AddRange(nextByte); } } Thread. Sleep(10); } catch (Exception) { } Thread. Sleep(1000); } } //Send a message public bool SendMsg(string msg) { //Send XXXX0001_000000000000_ (without underscore) // Receive 00570002_000000000000_010001020103 try { //data part byte[] bt_Data = Encoding.ASCII.GetBytes(msg); byte[] bt_head = Encoding.ASCII.GetBytes((bt_Data.Length + 4).ToString("0000")); byte[] bt_send = new byte[bt_Data. Length + 5]; for (int i = 0; i < bt_head. Length; i ++ ) { bt_send[i] = bt_head[i]; } for (int i = 0; i < bt_Data. Length; i ++ ) { bt_send[i + 4] = bt_Data[i]; } bt_send[bt_send.Length - 1] = 0x00; //Start sending asynchronously try { tcpClient.GetStream().BeginWrite(bt_send, 0, bt_send.Length, (ar) => { tcpClient.GetStream().EndWrite(ar);//End asynchronous sending }, null); } catch (Exception ex) { string abc = ex. ToString(); } return true; } catch (Exception ex) { SetCon(-1); SetCon(0); return false; } } public bool SendMsg(byte[] msg) { try { //Start sending asynchronously tcpClient.GetStream().BeginWrite(msg, 0, msg.Length, (ar) => { tcpClient.GetStream().EndWrite(ar);//End asynchronous sending }, null); return true; } catch (Exception ex) { // Attempt to reconnect. . . . . . " SetCon(-1); SetCon(0); return false; } } /// <summary> /// Disconnect /// </summary> public void Close() { IsClose = true; if (tcpClient != null) { try { tcpClient?.Close(); } catch (Exception) { } } } public int isConnected = -1; /// <summary> /// -1 initialization 0 not connected 1 connected /// </summary> /// <param name="_con"></param> private void SetCon(int _con) { if (isConnected != _con) { bool rel = false; if (_con == 1) { rel = true; } isConnected = _con; MyEventArgs e = new MyEventArgs(ip + "__" + port.ToString(), rel); _ConChange(e); } } private void PingOC() { Ping ping = new Ping(); int failcount = 0; while (!IsClose) { try { PingReply pingReply = ping.Send(ip, 1000); //network status if (pingReply.Status != IPStatus.Success) { failcount++; Form1.mt.Show("Ping, network failure, disconnection" + failcount.ToString() + "times", true, detailfilename); if (failcount > 2 & amp; & amp; isConnected != 0) { //If the communication fails in 3 seconds, the network has been disconnected! tcpClient.Client = null; tcpClient. Close(); } } else { failcount = 0; } Thread. Sleep(1000); } catch (Exception) { } } } public class MyEventArgs : EventArgs { public string IP; public bool IsConnect; public byte[] Msg; public string msg; public MyEventArgs(string iP, byte[] msg) { IP = IP; Msg = msg; } public MyEventArgs(string iP, string _msg) { IP = IP; msg = _msg; } public MyEventArgs(string iP, bool iscon) { IP = IP; IsConnect = iscon; } } //Connection Status public delegate void ConChange(object sender, MyEventArgs args); public event ConChange OnConChange; protected virtual void _ConChange(MyEventArgs e) { if (OnConChange != null) { OnConChange(this, e); } } //received message public delegate void MsgChange(object sender, MyEventArgs args); public event MsgChange OnMsgChange; protected virtual void _MsgChange(MyEventArgs e) { if (OnMsgChange != null) { OnMsgChange(this, e); } } } }
Call method:
AsyncTcpClient sw = new AsyncTcpClient(); sw.OnConChange += Sw_OnConChange; sw.OnMsgChange += Sw_OnMsgChange; sw.ConnectServer(ip, port); private void Sw_OnConChange(object sender, AsyncTcpClient.MyEventArgs args) { if (args. IsConnectct) { this.Invoke((EventHandler) delegate { timer1. Enabled = true; lab_Con.Text = "Online"; lab_Con.BackColor = Color.Green; timer1. Enabled = true; }); } else { this.Invoke((EventHandler) delegate { timer1. Enabled = false; lab_Con.Text = "Disconnect"; lab_Con.BackColor = Color.Red; timer1. Enabled = false; }); } } private static readonly object LOCK = new object(); private void Sw_OnMsgChange(object sender, AsyncTcpClient.MyEventArgs args) { //Add a lock and analyze item by item lock (LOCK) { //Show("Receive:" + args.msg); } } public void Close() { try { sw.OnConChange -= Sw_OnConChange; sw.OnMsgChange -= Sw_OnMsgChange; sw. Close(); } catch (Exception) { } }
Added message segmentation