using System; using System.Diagnostics; using System.Net.Sockets; using System.Threading; namespace Bro.Common.Link { public delegate void OnMessageRecv(byte[] dataBuff); /// /// TCP客户端连接 /// public class TCPClient : LinkBase { private static object synObj = new object(); // 服务器地址 public string ServerIP { get;set;} // 服务器IP public int ServerPort { get;set;} // 初始化标示 public bool IsInited { get;set; } public OnMessageRecv MessageRecv; // TCP客户端 public TcpClient Client = new TcpClient(); private Thread pollTask; // 停止标示 private bool bStop = false; public TCPClient() { IsInited = false; } /// /// 初始化 /// /// public override bool Init() { Client = new TcpClient(); // 接收发送缓存大小 Client.SendBufferSize = 4096; Client.ReceiveBufferSize = 4096; // 读写超时 Client.SendTimeout = 2000; Client.ReceiveTimeout = 100; IsInited = true; return true; } /// /// 销毁 /// public override void Fnit() { IsInited = false; if ( null == Client ) { return; } Client.Close(); } /// /// 连接服务器 /// /// public override bool Open() { try { if ( Client.Connected ) { Trace.TraceInformation("TCPClient:{0} dunpliated open", this.Desp); return true; } Client.Connect(ServerIP, ServerPort); //pollTask = new Thread(new ThreadStart(PollThread)); //pollTask.Start(); return true; } catch(Exception ex) { Trace.TraceError("TCPClient:{0} Open fail, ex:{1}-{2}", this.Desp, ex.Message, ex.StackTrace); } return false; } /// /// 关闭连接 /// public override void Close() { try { if ( !Client.Connected ) { return; } bStop = true; ClosePollTask(); Client.Close(); } catch(Exception ex) { Trace.TraceError("TCPClient:{0} Close fail, ex:{1}-{2}", this.Desp, ex.Message, ex.StackTrace); } } /// /// 判断对方是否在线,强制重新连接 /// public void ReConnect() { if(!Client.IsOnline()) { Close(); Init(); Open(); } } /// /// 接收数据 /// /// public override int Recv(byte[] rcvBuf, int offset) { int rcvLen = -1; if ( null == rcvBuf ) { return -1; } try { var len = rcvBuf.Length - offset; if ( len <= 0 ) { return -1; } rcvLen = Client.GetStream().Read(rcvBuf, offset, len); } catch(Exception ex) { Trace.TraceError("TCPClient:{0} Recv fail, ex:{1}-{2}", this.Desp, ex.Message, ex.StackTrace); return -1; } return rcvLen; } /// /// 发送数据 /// /// /// public override bool Send(byte[] sndBuf, int offset, int len) { if ( null == sndBuf ) { return false; } try { Client.GetStream().Write(sndBuf, offset, len); return true; } catch(Exception ex) { Trace.TraceError("TCPClient:{0} Send fail, ex:{1}-{2}", this.Desp, ex.Message, ex.StackTrace); } return false; } public void ClosePollTask() { pollTask?.Abort(); } public void StartPollTask() { pollTask = new Thread(new ThreadStart(PollThread)); pollTask.Start(); } /// /// 监听线程 /// private void PollThread() { for (; ; ) { lock (synObj) { if (bStop) break; var data = new byte[2048]; if (Recv(data, 0) > 0) { MessageRecv(data); } } } } } public static class TcpClientEx { public static bool IsOnline(this TcpClient c) { return !((c.Client.Poll(1000, SelectMode.SelectRead) && (c.Client.Available == 0)) || !c.Client.Connected); } } }