wxr
2023-06-06 592974441a4df95fffd9167c90192da1a390b1c2
HDL_ON/DAL/DriverLayer/Control_TcpClient.cs
@@ -1,7 +1,12 @@
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks;
using HDL_ON.Entity;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace HDL_ON.DriverLayer
{
@@ -11,11 +16,76 @@
        //声明IP,端口,和一个用来连接的Socket
        public string _ip;
        private TcpClient _tcpClient;
        private TcpClient _clinet;
        private TcpClient _tcpClient {
            get
            {
                return _clinet;
            }
            set
            {
                _clinet = value;
                if (_clinet == null) {
                    if(connectThread!= null)
                    {
                        connectThread.Abort();
                        connectThread = null;
                    }
                }
            }
        }
        //创建一个委托,用来满足其他类调用
        //public delegate void DelegateMessage(string str);
        public Action<string> ReceiveEvent;
        /// <summary>
        /// 连接次数
        /// </summary>
        private int reconnectIndex = 0;
        private bool _isConnected = false;
        /// <summary>
        /// 是否连接成功
        /// </summary>
        public bool isConnected {
            get
            {
                return _isConnected;
            }
            set
            {
                _isConnected = value;
                if (value)
                {
                    Control.Ins.LoginGateway();
                    HeartBeat();
                }
                else
                {
                    try
                    {
                        _tcpClient.Close();
                        _tcpClient = null;
                    }
                    catch (Exception)
                    {
                    }
                }
            }
        }
        private List<string> heartBeatLogIdList = new List<string>();
        /// <summary>
        /// 心跳记录
        /// </summary>
        public void ClearHeartBeatLog()
        {
            heartBeatLogIdList.Clear();
        }
        /// <summary>
        /// 构造函数
@@ -26,26 +96,115 @@
        }
        //TCP连接
        public bool Connect(int _port = 8586)
        private bool ConnectToTcp( )
        {
            if (string.IsNullOrEmpty(_ip) || _port == 0)
            if (string.IsNullOrEmpty(_ip) )
            {
                return false;
            }
            _tcpClient = new TcpClient();
            if (_tcpClient == null)
            {
                _tcpClient = new TcpClient();
            }
            try
            {
                _tcpClient.Connect(IPAddress.Parse(_ip), _port);
                Task.Run(new Action(ReceiveMessage));//开启线程,不停接收消息
                MainPage.Log($"打开tcp client{_ip}:{_port}");
                _tcpClient.Connect(IPAddress.Parse(_ip), 8586);
                ReceiveMessage();//开启线程,不停接收消息
                MainPage.Log($"打开tcp client{_ip}:8586");
                isConnected = true;
            }
            catch (Exception e)
            {
                MainPage.Log(e.Message);
                throw;
                MainPage.Log($"打开tcp异常:"+e.Message);
                return false;
            }
            return true;//返回连接状态
        }
        /// <summary>
        /// 连接tcp线程
        /// </summary>
        private Thread connectThread;
        /// <summary>
        /// 连接线程
        /// </summary>
        public void Connect()
        {
            lock (lockObj)
            {
                if (isConnected)
                {
                    return;
                }
                if (connectThread == null)
                {
                    connectThread = new Thread(() =>
                    {
                        while (Control.Ins.GatewayOnline_Local && !isConnected)
                        {
                            if (_tcpClient == null)
                            {
                                ConnectToTcp();
                            }
                            else
                            {
                                if (!_tcpClient.Connected)
                                {
                                    try
                                    {
                                        //_tcpClient.ReceiveTimeout =
                                        _tcpClient.Connect(IPAddress.Parse(_ip), 8586);
                                        ReceiveMessage();//开启线程,不停接收消息
                                        isConnected = true;
                                    }
                                    catch (Exception ex)
                                    {
                                        MainPage.Log($"tcp重连异常:{ex.Message}");
                                    }
                                }
                            }
                            Thread.Sleep(1000);
                        }
                    });
                    connectThread.Start();
                }
                else
                {
                    if (!isConnected)
                    {
                        try
                        {
                            connectThread?.Abort();
                        }
                        catch { }
                        finally
                        {
                            connectThread = null;
                        }
                        Connect();
                    }
                }
            }
        }
        /// <summary>
        /// 重连
        /// </summary>
        public void Reconect()
        {
            if (_tcpClient == null)
            {
                Connect();
            }
            else
            {
                _tcpClient.Close();
                _tcpClient = null;
                Connect();
            }
        }
        /// <summary>
        /// 关闭连接
        /// </summary>
@@ -65,70 +224,174 @@
        /// <param name="bytes">需要发送的字节</param>
        public void SendMessage(byte[] bytes)
        {
            NetworkStream networkStream = _tcpClient.GetStream();
            if (networkStream.CanWrite)
            if (heartBeatLogIdList.Count > 3)
            {
                networkStream.Write(bytes, 0, bytes.Length);
                try
                {
                    MainPage.Log("心跳多次未回复,断开tcp连接");
                    heartBeatLogIdList.Clear();
                    isConnected = false;
                    Reconect();
                    return;
                }catch (Exception ex)
                {
                    MainPage.Log($"重连tcp异常:{ex.Message}");
                }
            }
            //networkStream.Close();
            try
            {
                if (_tcpClient.GetStream().CanWrite&& isConnected)
                {
                    _tcpClient.GetStream().Write(bytes, 0, bytes.Length);
                }
            }catch(Exception ex)
            {
                MainPage.Log($"tcp客户端发送数据异常:{ex.Message}");
                isConnected = false;
            }
        }
        /// <summary>
        /// 获取列表数据回调方法
        /// 心跳包线程
        /// </summary>
        public Action<string> GetListResponseAction;
        private Thread heartBeatThread;
        private DateTime heartBeatTime;
        public void HeartBeat()
        {
            lock (lockObj)
            {
                if (heartBeatThread == null)
                {
                    MainPage.Log($"心跳包线程启动");
                    heartBeatThread = new Thread(() =>
                    {
                        while (isConnected)
                        {
                            if (_tcpClient.Connected && 10 * 1000 < (System.DateTime.Now - heartBeatTime).TotalMilliseconds)
                            {
                                string msgId = Control.Ins.msg_id.ToString();
                                heartBeatLogIdList.Add(msgId);
                                var sendJob = new JObject { { "id", Control.Ins.msg_id.ToString() }, { "time_stamp", Utlis.GetTimestamp() } };
                                var bodyString = JsonConvert.SerializeObject(sendJob);
                                var sendBytes = Control.Ins.ConvertSendBodyData(CommunicationTopic.ct.HeartBeat, bodyString, false);
                                SendMessage(sendBytes);
                                heartBeatTime = DateTime.Now;
                            }
                            Thread.Sleep(100);
                        }
                    });
                    heartBeatThread.Start();
                }
                else
                {
                    try
                    {
                        heartBeatThread?.Abort();
                    }
                    catch (Exception ex)
                    {
                        MainPage.Log($"启动心跳线程,重启线程异常:{ex.Message}");
                    }
                    finally
                    {
                        if (heartBeatThread != null)
                        {
                            heartBeatThread = null;
                        }
                        HeartBeat();
                    }
                }
            }
        }
        /// <summary>
        /// 接收数据线程
        /// </summary>
        private Thread receiveThread;
        private object lockObj = new object();
        //接收消息
        public void ReceiveMessage()
        {
            NetworkStream networkStream = _tcpClient.GetStream();
            while (true)
            lock (lockObj)
            {
                // 定义一个2M的缓存区;
                byte[] arrMsgRec = new byte[1024 * 1024 * 2];
                int size = networkStream.Read(arrMsgRec, 0, arrMsgRec.Length);
                var tcpDataString = System.Text.Encoding.UTF8.GetString(arrMsgRec, 0, arrMsgRec.Length);
                if (!string.IsNullOrEmpty(tcpDataString))
                if (receiveThread == null)
                {
                    ReceiveEvent?.Invoke(tcpDataString);
                    receiveThread = new Thread(() =>
                    {
                        try
                        {
                            while (isConnected)
                            {
                                if (_tcpClient == null)
                                {
                                    try
                                    {
                                        receiveThread?.Abort();
                                    }
                                    catch { }
                                    finally
                                    {
                                        receiveThread = null;
                                    }
                                    return;
                                }
                                if (!_tcpClient.Connected)
                                {
                                    MainPage.Log("tcp客户端断开了连接...");
                                    isConnected = false;
                                    return;
                                }
                                try
                                {
                                    // 定义一个2M的缓存区;
                                    byte[] arrMsgRec = new byte[1024 * 1024 * 2];
                                    try
                                    {
                                        int size = _tcpClient.GetStream().Read(arrMsgRec, 0, arrMsgRec.Length);
                                    }
                                    catch (Exception ex)
                                    {
                                        isConnected = false;
                                        MainPage.Log($"局域网tcp数据接收异常:{ex.Message}");
                                        return;
                                    }
                                    var tcpDataString = System.Text.Encoding.UTF8.GetString(arrMsgRec, 0, arrMsgRec.Length);
                                    if (!string.IsNullOrEmpty(tcpDataString))
                                    {
                                        MainPage.Log($"局域网tcp数据接收");
                                        Control.Ins.ConvertReceiveData(arrMsgRec, null);
                                    }
                                }
                                catch (Exception) { }
                            }
                        }catch (Exception ex)
                        {
                            MainPage.Log($"tcp ReceiveMessage error :{ex.Message}");
                        }
                    });
                    //receiveThread.IsBackground = true;
                    receiveThread.Start();
                }
                //// 将接受到的数据存入到输入  arrMsgRec中;
                //int length = -1;
                //try
                //{
                //    length = socketClient.Receive(arrMsgRec); // 接收数据,并返回数据的长度;
                //}
                //catch (Exception ex)
                //{
                //    MainPage.Log($"tcpListener  error 1 :  {ex.Message}");
                //    Flag_Receive = false;
                //    // 从通信线程集合中删除被中断连接的通信线程对象;
                //    string keystr = socketClient.RemoteEndPoint.ToString();
                //    dic_ClientSocket.Remove(keystr);//删除客户端字典中该socket
                //    dic_ClientThread[keystr].Abort();//关闭线程
                //    dic_ClientThread.Remove(keystr);//删除字典中该线程
                //    tcpClient = null;
                //    socketClient = null;
                //    break;
                //}
                //byte[] buf = new byte[length];
                //Array.Copy(arrMsgRec, buf, length);
                //lock (tcpClient.m_Buffer)
                //{
                //    var tcpDataString = System.Text.Encoding.UTF8.GetString(arrMsgRec, 0, length);
                //    if (!string.IsNullOrEmpty(tcpDataString))
                //    {
                //        ReceiveEvent?.Invoke(tcpDataString);
                //    }
                //    MainPage.Log($"接收服务端数据:{tcpDataString}");
                //}
                else
                {
                    try
                    {
                        receiveThread?.Abort();
                    }
                    catch { }
                    finally
                    {
                        receiveThread = null;
                        ReceiveMessage();
                    }
                }
            }
        }
    }
}