版博士V2.0程序
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

180 line
5.1 KiB

  1. using System;
  2. using System.Collections.Concurrent;
  3. using System.Collections.Generic;
  4. using System.IO.Ports;
  5. using System.Linq;
  6. using System.Text;
  7. using System.Threading;
  8. using System.Threading.Tasks;
  9. namespace AssistClient.Utils
  10. {
  11. public class SSerialPort
  12. {
  13. private SerialPort _serialPort;
  14. private readonly ConcurrentQueue<byte[]> _messageQueue;
  15. private readonly EventWaitHandle _messageWaitHandle;
  16. private int _receiveCount, _sendCount;
  17. private readonly object _lock;
  18. private int queueSize;
  19. public int ReceiveCount
  20. {
  21. get => _receiveCount;
  22. }
  23. public int SendCount
  24. {
  25. get => _sendCount;
  26. }
  27. public SSerialPort(string com, int baud,int size=-1)
  28. {
  29. // initialized
  30. _lock = new object();
  31. _receiveCount = 0;
  32. _sendCount = 0;
  33. _messageQueue = new ConcurrentQueue<byte[]>();
  34. _messageWaitHandle = new EventWaitHandle(false, EventResetMode.AutoReset);
  35. queueSize = size;
  36. // Open Com
  37. openCom(com.ToUpper(), baud);
  38. // Receive byte
  39. pushMessage();
  40. }
  41. private void openCom(string com, int baud)
  42. {
  43. // Open Com
  44. _serialPort = new SerialPort(com, baud);
  45. if (_serialPort.IsOpen) _serialPort.Close();
  46. // Set the read / write timeouts
  47. _serialPort.ReadTimeout = 500;
  48. _serialPort.WriteTimeout = 500;
  49. // Set read / write buffer Size,the default of value is 1MB
  50. _serialPort.ReadBufferSize = 1024 * 1024;
  51. _serialPort.WriteBufferSize = 1024 * 1024;
  52. _serialPort.Open();
  53. // Discard Buffer
  54. _serialPort.DiscardInBuffer();
  55. _serialPort.DiscardOutBuffer();
  56. }
  57. #region Static
  58. /// <summary>
  59. /// 获取当前计算机的串行端口名的数组
  60. /// </summary>
  61. /// <returns></returns>
  62. public static string[] getPortNames()
  63. {
  64. return SerialPort.GetPortNames();
  65. }
  66. #endregion
  67. #region Receive
  68. private void pushMessage()
  69. {
  70. _serialPort.DataReceived += (sender, e) =>
  71. {
  72. lock (_lock)
  73. {
  74. if (_serialPort.IsOpen == false) return;
  75. int length = _serialPort.BytesToRead;
  76. byte[] buffer = new byte[length];
  77. _serialPort.Read(buffer, 0, length);
  78. _receiveCount += length;
  79. _messageQueue.Enqueue(buffer);
  80. byte[] outObj;
  81. while (queueSize>0 && _messageQueue.Count > queueSize)
  82. {
  83. _messageQueue.TryDequeue(out outObj);
  84. }
  85. _messageWaitHandle.Set();
  86. }
  87. };
  88. }
  89. /// <summary>
  90. /// 获取串口接受到的内容
  91. /// </summary>
  92. /// <param name="millisecondsToTimeout">取消息的超时时间</param>
  93. /// <returns>返回byte数组</returns>
  94. public byte[] getMessage(int millisecondsToTimeout = -1)
  95. {
  96. if (_messageQueue.TryDequeue(out var message))
  97. {
  98. return message;
  99. }
  100. if (_messageWaitHandle.WaitOne(millisecondsToTimeout))
  101. {
  102. if (_messageQueue.TryDequeue(out message))
  103. {
  104. return message;
  105. }
  106. }
  107. return default;
  108. }
  109. #endregion
  110. #region Send
  111. /// <summary>
  112. /// 发送消息(byte数组)
  113. /// </summary>
  114. /// <param name="buffer"></param>
  115. /// <param name="offset"></param>
  116. /// <param name="count"></param>
  117. public void send(byte[] buffer, int offset, int count)
  118. {
  119. lock (_lock)
  120. {
  121. _serialPort.Write(buffer, offset, count);
  122. //_sendCount += (count - offset);
  123. _sendCount += count;
  124. }
  125. }
  126. /// <summary>
  127. /// 发送消息(字符串)
  128. /// </summary>
  129. /// <param name="encoding">字符串编码方式,具体方式见<see cref="Encoding"/></param>
  130. /// <param name="message"></param>
  131. public void send(Encoding encoding, string message)
  132. {
  133. lock (_lock)
  134. {
  135. var buffer = encoding.GetBytes(message);
  136. _serialPort.Write(buffer, 0, buffer.Length);
  137. _sendCount += buffer.Length;
  138. }
  139. }
  140. #endregion
  141. /// <summary>
  142. /// 清空接受/发送总数统计
  143. /// </summary>
  144. public void clearCount()
  145. {
  146. lock (_lock)
  147. {
  148. _sendCount = 0;
  149. _receiveCount = 0;
  150. }
  151. }
  152. /// <summary>
  153. /// 关闭串口
  154. /// </summary>
  155. public void close()
  156. {
  157. _serialPort.Close();
  158. }
  159. }
  160. }