using Cowain.Bake.Common.Core; using HslCommunication; using HslCommunication.Core.Net; using System; using System.Net.Sockets; using System.Text; using System.Threading; namespace Cowain.Bake.Communication.Sokects { public class TcpSocketClient : NetworkXBase { private Encoding encoding; private object connectLock = new object(); public string Ip { get; set; } = "127.0.0.1"; public int Port { get; set; } = 10000; // 声明一个事件,通知变量变化 // 定义委托 public delegate void ValueChangedEventHandler(object sender, EventArgs e); // 声明事件 public event ValueChangedEventHandler ValueChanged; private bool _isConnected; public bool IsConnected { get { return _isConnected; } set { _isConnected = value; OnValueChanged(); } } //CoreSocket.Connected private int bufferLength = 2048; private byte[] buffer = null; // 触发事件的方法 public virtual void OnValueChanged() { ValueChanged?.Invoke(this, EventArgs.Empty); } /// /// 当前的编码器 /// public Encoding Encoding { get { return encoding; } set { encoding = value; } } /// /// 当接收到字符串时候的触发事件 /// public event Action ReceivedString; /// /// 实例化一个默认的对象 /// //public TcpSocketClient() //{ // buffer = new byte[bufferLength]; // encoding = Encoding.UTF8; //} /// /// 使用指定的ip地址和端口号来实例化这个对象 /// /// Ip地址 /// 端口号 public TcpSocketClient(string ipAddress, int port) { buffer = new byte[bufferLength]; encoding = Encoding.UTF8; this.Ip = ipAddress; this.Port = port; } /// /// 连接服务器 /// /// 返回是否连接成功 public OperateResult ConnectServer() { CoreSocket?.Close(); OperateResult operateResult = CreateSocketAndConnect(Ip, Port, 5000); IsConnected = operateResult.IsSuccess; if (!operateResult.IsSuccess) { return operateResult; } try { CoreSocket = operateResult.Content; CoreSocket.BeginReceive(buffer, 0, bufferLength, SocketFlags.None, ReceiveCallBack, CoreSocket); return OperateResult.CreateSuccessResult(); } catch (Exception ex) { LogHelper.Instance.Error("连接MOM系统失败!", true); return new OperateResult(ex.Message); } } /// /// 关闭当前的连接对象 /// /// 错误信息 public OperateResult ConnectClose() { try { CoreSocket?.Close(); return OperateResult.CreateSuccessResult(); } catch (Exception ex) { return new OperateResult(ex.Message); } } /// /// 发送字符串到网络上去 /// /// 文本信息 /// 发送是否成功 public OperateResult SendString(string text) { if (string.IsNullOrEmpty(text)) { return OperateResult.CreateSuccessResult(); } return Send(CoreSocket, encoding.GetBytes(text)); } public OperateResult Send(byte[] text) { return Send(CoreSocket, text); } private void ReceiveCallBack(IAsyncResult ar) { Socket socket = ar.AsyncState as Socket; if (socket == null) { return; } byte[] array = null; try { int num = socket.EndReceive(ar); socket.BeginReceive(buffer, 0, bufferLength, SocketFlags.None, ReceiveCallBack, socket); if (num == 0) { IsConnected = false; CoreSocket?.Close(); return; } array = new byte[num]; Array.Copy(buffer, 0, array, 0, num); } catch (ObjectDisposedException) { } catch (Exception ex2) { base.LogNet?.WriteWarn(StringResources.Language.SocketContentReceiveException + ":" + ex2.Message); ThreadPool.QueueUserWorkItem(ReConnectServer, null); } if (array != null) { this.ReceivedString?.Invoke(encoding.GetString(array)); } } /// /// 是否是处于重连的状态 /// /// 无用的对象 public void ReConnectServer(object obj) { base.LogNet?.WriteWarn(StringResources.Language.ReConnectServerAfterTenSeconds); for (int i = 0; i < 10; i++) { Thread.Sleep(1000); base.LogNet?.WriteWarn($"Wait for connecting server after {9 - i} seconds"); } OperateResult operateResult = CreateSocketAndConnect(Ip, Port, 5000); IsConnected = operateResult.IsSuccess; if (!operateResult.IsSuccess) { //用于将工作项添加到线程池的方法。它允许你将一个委托(Delegate)或方法作为参数添加到线程池中,以便由线程池中的线程执行 //ThreadPool.QueueUserWorkItem(ReConnectServer, obj); //加上它,只要一次重连就可以了,不加他,就可以执行多次。add by lsm return; } lock (connectLock) { try { CoreSocket?.Close(); CoreSocket = operateResult.Content; CoreSocket.BeginReceive(buffer, 0, bufferLength, SocketFlags.None, ReceiveCallBack, CoreSocket); base.LogNet?.WriteWarn(StringResources.Language.ReConnectServerSuccess); } catch (Exception ex) { base.LogNet?.WriteWarn(StringResources.Language.RemoteClosedConnection + ":" + ex.Message); ThreadPool.QueueUserWorkItem(ReConnectServer, obj); } } } /// /// 返回表示当前对象的字符串 /// /// 字符串 public override string ToString() { return $"NetPlainSocket[{Ip}:{Port}]"; } } }