|
- using System;
- using System.Collections.Concurrent;
- using System.Collections.Generic;
- using System.IO.Ports;
- using System.Linq;
- using System.Text;
- using System.Threading;
- using System.Threading.Tasks;
-
- namespace AssistClient.Utils
- {
- public class SSerialPort
- {
- private SerialPort _serialPort;
- private readonly ConcurrentQueue<byte[]> _messageQueue;
- private readonly EventWaitHandle _messageWaitHandle;
- private int _receiveCount, _sendCount;
- private readonly object _lock;
- private int queueSize;
- public int ReceiveCount
- {
- get => _receiveCount;
- }
- public int SendCount
- {
- get => _sendCount;
- }
- public SSerialPort(string com, int baud,int size=-1)
- {
- // initialized
- _lock = new object();
- _receiveCount = 0;
- _sendCount = 0;
- _messageQueue = new ConcurrentQueue<byte[]>();
- _messageWaitHandle = new EventWaitHandle(false, EventResetMode.AutoReset);
- queueSize = size;
- // Open Com
- openCom(com.ToUpper(), baud);
-
- // Receive byte
- pushMessage();
- }
-
- private void openCom(string com, int baud)
- {
- // Open Com
- _serialPort = new SerialPort(com, baud);
- if (_serialPort.IsOpen) _serialPort.Close();
-
- // Set the read / write timeouts
- _serialPort.ReadTimeout = 500;
- _serialPort.WriteTimeout = 500;
-
- // Set read / write buffer Size,the default of value is 1MB
- _serialPort.ReadBufferSize = 1024 * 1024;
- _serialPort.WriteBufferSize = 1024 * 1024;
-
- _serialPort.Open();
-
- // Discard Buffer
- _serialPort.DiscardInBuffer();
- _serialPort.DiscardOutBuffer();
- }
-
-
- #region Static
- /// <summary>
- /// 获取当前计算机的串行端口名的数组
- /// </summary>
- /// <returns></returns>
- public static string[] getPortNames()
- {
- return SerialPort.GetPortNames();
- }
- #endregion
-
- #region Receive
- private void pushMessage()
- {
- _serialPort.DataReceived += (sender, e) =>
- {
- lock (_lock)
- {
- if (_serialPort.IsOpen == false) return;
- int length = _serialPort.BytesToRead;
- byte[] buffer = new byte[length];
- _serialPort.Read(buffer, 0, length);
- _receiveCount += length;
- _messageQueue.Enqueue(buffer);
-
- byte[] outObj;
- while (queueSize>0 && _messageQueue.Count > queueSize)
- {
- _messageQueue.TryDequeue(out outObj);
- }
- _messageWaitHandle.Set();
- }
- };
- }
-
- /// <summary>
- /// 获取串口接受到的内容
- /// </summary>
- /// <param name="millisecondsToTimeout">取消息的超时时间</param>
- /// <returns>返回byte数组</returns>
- public byte[] getMessage(int millisecondsToTimeout = -1)
- {
- if (_messageQueue.TryDequeue(out var message))
- {
- return message;
- }
-
- if (_messageWaitHandle.WaitOne(millisecondsToTimeout))
- {
- if (_messageQueue.TryDequeue(out message))
- {
- return message;
- }
- }
- return default;
- }
- #endregion
-
-
- #region Send
- /// <summary>
- /// 发送消息(byte数组)
- /// </summary>
- /// <param name="buffer"></param>
- /// <param name="offset"></param>
- /// <param name="count"></param>
- public void send(byte[] buffer, int offset, int count)
- {
- lock (_lock)
- {
- _serialPort.Write(buffer, offset, count);
- //_sendCount += (count - offset);
- _sendCount += count;
- }
- }
-
- /// <summary>
- /// 发送消息(字符串)
- /// </summary>
- /// <param name="encoding">字符串编码方式,具体方式见<see cref="Encoding"/></param>
- /// <param name="message"></param>
- public void send(Encoding encoding, string message)
- {
- lock (_lock)
- {
- var buffer = encoding.GetBytes(message);
- _serialPort.Write(buffer, 0, buffer.Length);
- _sendCount += buffer.Length;
- }
- }
- #endregion
-
- /// <summary>
- /// 清空接受/发送总数统计
- /// </summary>
- public void clearCount()
- {
- lock (_lock)
- {
- _sendCount = 0;
- _receiveCount = 0;
- }
- }
-
- /// <summary>
- /// 关闭串口
- /// </summary>
- public void close()
- {
- _serialPort.Close();
- }
- }
-
- }
|