180 lines
5.1 KiB
C#
180 lines
5.1 KiB
C#
|
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();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
}
|