TcpClientBase.cs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Net.Sockets;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. namespace SKMC.Api.Common.Tcp
  8. {
  9. public class TcpClientBase
  10. {
  11. protected static readonly ILogger log = LogFactory.Get();
  12. public string Address { get; set; } = "127.0.0.1";
  13. public int Port { get; set; }
  14. public int TIMEOUT { get; set; } = 5000;
  15. // 是否长连接
  16. public bool KeepAlived { get; set; } = false;
  17. // 测试模式(空跑模式)下, 不等待接收响应
  18. public bool TestMode { get; set; } = false;
  19. // 是否开启
  20. public bool Enabled { get; set; } = true;
  21. public bool Logged { get; set; } = true;
  22. // 是否运行中, 结束运行可放弃等待服务端响应数据
  23. public bool Running { get; set; }
  24. private TCPClient client;
  25. public TcpClientBase(string address, int port)
  26. {
  27. Address = address;
  28. Port = port;
  29. client = new TCPClient(Address, Port) { KeepAlived = KeepAlived };
  30. }
  31. /// <summary>
  32. /// 保持连接, 如果连接已中断则重新连接
  33. /// </summary>
  34. /// <param name="mills">验证连接的超时时间(ms)</param>
  35. /// <returns></returns>
  36. public TCPClient Connect(int mills)
  37. {
  38. if (!Enabled) return null;
  39. if (!KeepAlived || !client.IsConnected(mills))
  40. {
  41. client.Connect();
  42. }
  43. return client;
  44. }
  45. public TCPClient Connect()
  46. {
  47. if (!Enabled) return null;
  48. if (client != null) client.Connect();
  49. return client;
  50. }
  51. public void Reset(int index)
  52. {
  53. if (client != null) client.Clear();
  54. Running = false;
  55. }
  56. /// <summary>
  57. /// 请求并获取结果
  58. /// 请求后阻塞获取确认消息
  59. /// 再异步接收结果
  60. /// </summary>
  61. /// <param name="requestMsg">请求消息</param>
  62. /// <param name="responseAction">响应结果解析</param>
  63. /// <returns></returns>
  64. public Task RequestAndResult(string requestMsg, bool sync = false, Action<string> responseAction = null, Action<string> resultAction = null)
  65. {
  66. string response = null;
  67. string result = null;
  68. try
  69. {
  70. client = Connect(100);
  71. Reset(0);
  72. client.Send(requestMsg, Logged);
  73. response = client.Recevie(Logged);
  74. if (sync)
  75. {
  76. resultAction?.Invoke(response);
  77. if (!KeepAlived) client.Close();
  78. }
  79. else
  80. {
  81. // 异步模式, 视觉采图响应
  82. try
  83. {
  84. responseAction?.Invoke(response);
  85. }
  86. catch (Exception e)
  87. {
  88. throw new Exception($"Response Parse(Aync) Error", e);
  89. }
  90. }
  91. if (sync) return null;
  92. return Task.Run(() =>
  93. {
  94. try
  95. {
  96. result = client.Recevie(Logged);
  97. resultAction?.Invoke(result);
  98. if (!KeepAlived) client.Close();
  99. }
  100. catch (Exception e)
  101. {
  102. throw new Exception($"Result Parse(Aync) Error", e);
  103. }
  104. });
  105. }
  106. catch (SocketException ex)
  107. {
  108. switch ((SocketError)ex.ErrorCode)
  109. {
  110. case SocketError.TimedOut:
  111. throw new Exception($"接收超时: [{Address} : {Port}]", ex);
  112. case SocketError.ConnectionRefused:
  113. throw new Exception($"连接被拒绝: [{Address} : {Port}]", ex);
  114. case SocketError.HostNotFound:
  115. throw new Exception($"地址未找到: [{Address} : {Port}]", ex);
  116. case SocketError.NetworkDown:
  117. throw new Exception($"网络不可用: [{Address} : {Port}]", ex);
  118. case SocketError.AddressAlreadyInUse:
  119. throw new Exception($"地址已被使用: [{Address} : {Port}]", ex);
  120. default:
  121. throw new Exception($"其他Socket异常: [{Address} : {Port}]", ex);
  122. }
  123. }
  124. catch (Exception e)
  125. {
  126. throw e;
  127. }
  128. }
  129. }
  130. }