using System; using System.Collections.Generic; using System.Linq; using System.Net.Sockets; using System.Text; using System.Threading.Tasks; namespace SKMC.Api.Common.Tcp { public class TcpClientBase { protected static readonly ILogger log = LogFactory.Get(); public string Address { get; set; } = "127.0.0.1"; public int Port { get; set; } public int TIMEOUT { get; set; } = 5000; // 是否长连接 public bool KeepAlived { get; set; } = false; // 测试模式(空跑模式)下, 不等待接收响应 public bool TestMode { get; set; } = false; // 是否开启 public bool Enabled { get; set; } = true; public bool Logged { get; set; } = true; // 是否运行中, 结束运行可放弃等待服务端响应数据 public bool Running { get; set; } private TCPClient client; public TcpClientBase(string address, int port) { Address = address; Port = port; client = new TCPClient(Address, Port) { KeepAlived = KeepAlived }; } /// /// 保持连接, 如果连接已中断则重新连接 /// /// 验证连接的超时时间(ms) /// public TCPClient Connect(int mills) { if (!Enabled) return null; if (!KeepAlived || !client.IsConnected(mills)) { client.Connect(); } return client; } public TCPClient Connect() { if (!Enabled) return null; if (client != null) client.Connect(); return client; } public void Reset(int index) { if (client != null) client.Clear(); Running = false; } /// /// 请求并获取结果 /// 请求后阻塞获取确认消息 /// 再异步接收结果 /// /// 请求消息 /// 响应结果解析 /// public Task RequestAndResult(string requestMsg, bool sync = false, Action responseAction = null, Action resultAction = null) { string response = null; string result = null; try { client = Connect(100); Reset(0); client.Send(requestMsg, Logged); response = client.Recevie(Logged); if (sync) { resultAction?.Invoke(response); if (!KeepAlived) client.Close(); } else { // 异步模式, 视觉采图响应 try { responseAction?.Invoke(response); } catch (Exception e) { throw new Exception($"Response Parse(Aync) Error", e); } } if (sync) return null; return Task.Run(() => { try { result = client.Recevie(Logged); resultAction?.Invoke(result); if (!KeepAlived) client.Close(); } catch (Exception e) { throw new Exception($"Result Parse(Aync) Error", e); } }); } catch (SocketException ex) { switch ((SocketError)ex.ErrorCode) { case SocketError.TimedOut: throw new Exception($"接收超时: [{Address} : {Port}]", ex); case SocketError.ConnectionRefused: throw new Exception($"连接被拒绝: [{Address} : {Port}]", ex); case SocketError.HostNotFound: throw new Exception($"地址未找到: [{Address} : {Port}]", ex); case SocketError.NetworkDown: throw new Exception($"网络不可用: [{Address} : {Port}]", ex); case SocketError.AddressAlreadyInUse: throw new Exception($"地址已被使用: [{Address} : {Port}]", ex); default: throw new Exception($"其他Socket异常: [{Address} : {Port}]", ex); } } catch (Exception e) { throw e; } } } }