You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
305 lines
9.6 KiB
C#
305 lines
9.6 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
using System.IO.Ports;
|
|
using System.Threading;
|
|
using System.Collections;
|
|
using HuizhongLibrary.Network;
|
|
using HuizhongLibrary.Log;
|
|
|
|
namespace HuizhongLibrary
|
|
{
|
|
public class SerialPortService
|
|
{
|
|
private Byte[] m_Data;
|
|
public Byte[] Data
|
|
{
|
|
get { return m_Data; }
|
|
set { m_Data = value; }
|
|
}
|
|
private List<byte> m_SocketBuffer = new List<byte>();
|
|
/// <summary>
|
|
/// 网络数据缓存
|
|
/// </summary>
|
|
public List<byte> SocketBuffer
|
|
{
|
|
get { return m_SocketBuffer; }
|
|
set { m_SocketBuffer = value; }
|
|
}
|
|
private int m_RefshSecond = 30;
|
|
public int RefshSecond
|
|
{
|
|
get { return m_RefshSecond; }
|
|
set { m_RefshSecond = value; }
|
|
}
|
|
private int m_MaxWaitMsgNumber = 1;
|
|
/// <summary>
|
|
/// 最大消息等待回包数量(滑动窗口)
|
|
/// </summary>
|
|
public int MaxWaitMsgNumber
|
|
{
|
|
get { return m_MaxWaitMsgNumber; }
|
|
set { m_MaxWaitMsgNumber = value; }
|
|
}
|
|
private int m_ReadBufferSize = 4096;
|
|
public int ReadBufferSize
|
|
{
|
|
get { return m_ReadBufferSize; }
|
|
set { m_ReadBufferSize = value; }
|
|
}
|
|
private int m_WriteBufferSize = 4096;
|
|
public int WriteBufferSize
|
|
{
|
|
get { return m_WriteBufferSize; }
|
|
set { m_WriteBufferSize = value; }
|
|
}
|
|
private string m_StringNewLine = "0";
|
|
/// <summary>
|
|
/// 读取数据的方式(0 byte方式读取1按回车读取
|
|
/// </summary>
|
|
public string StringNewLine
|
|
{
|
|
get { return m_StringNewLine; }
|
|
set { m_StringNewLine = value; }
|
|
}
|
|
public int ReadSleep = 0;
|
|
public bool IsRunSendThread = true;
|
|
public int MaxSendNumber = 0;
|
|
|
|
|
|
public event Action<SerialPort> ReceiveData;
|
|
public event Action<SerialPort> SendData;
|
|
public event Action<string> ReceiveString;
|
|
/// <summary>
|
|
/// 超出最大发送次数
|
|
/// </summary>
|
|
public event Action<SocketMessage> OverMaxSend;
|
|
|
|
public SocketMessages ListMessage = new SocketMessages();
|
|
public int WaitMsgNumber = 0;
|
|
private AutoResetEvent AutoReset = new AutoResetEvent(false);
|
|
private bool IsRun = false;
|
|
private DateTime CacheDataTime = DateTime.Now;
|
|
|
|
public SerialPortService()
|
|
{
|
|
|
|
}
|
|
SerialPort comm = null;
|
|
#region 使用串口通讯
|
|
public void Start(string PortName, int BaudRate, int DataBits, Parity par, StopBits sBits)
|
|
{
|
|
comm = new SerialPort();
|
|
comm.ReadBufferSize = ReadBufferSize;
|
|
comm.WriteBufferSize = WriteBufferSize;
|
|
comm.PortName = PortName;
|
|
comm.BaudRate = BaudRate;
|
|
comm.DataBits = DataBits;
|
|
comm.Parity = par;
|
|
comm.StopBits = sBits;
|
|
//comm.ReadTimeout = 500;
|
|
//comm.WriteTimeout = 500;
|
|
comm.NewLine = StringNewLine;
|
|
comm.Encoding = Encoding.Default;
|
|
comm.DataReceived += new SerialDataReceivedEventHandler(comm_DataReceived);
|
|
comm.Open();
|
|
if (IsRunSendThread == true)
|
|
{
|
|
IsRun = true;
|
|
Thread t1 = new Thread(new ThreadStart(this.WhileListUserSocket));
|
|
t1.Start();
|
|
}
|
|
}
|
|
#endregion
|
|
#region 停止通讯
|
|
public void Stop()
|
|
{
|
|
this.IsRun = false;
|
|
if (comm!=null)comm.Close();
|
|
}
|
|
#endregion
|
|
#region 读取到数据发生
|
|
void comm_DataReceived(object sender, SerialDataReceivedEventArgs e)
|
|
{
|
|
if (ReadSleep > 0) Thread.Sleep(ReadSleep);
|
|
if (this.StringNewLine == "0")
|
|
{
|
|
int ReceiveLen = comm.BytesToRead;//先记录下来,避免某种原因,人为的原因,操作几次之间时间长,缓存不一致
|
|
byte[] Bytes = new byte[ReceiveLen];//声明一个临时数组存储当前来的串口数据
|
|
comm.Read(Bytes, 0, ReceiveLen);
|
|
AddData(Bytes, ReceiveLen);
|
|
if (this.ReceiveData != null) this.ReceiveData(comm);
|
|
}
|
|
else
|
|
{
|
|
try
|
|
{
|
|
while (true)
|
|
{
|
|
if (comm.BytesToRead == 0) return;
|
|
string RevData = comm.ReadLine();
|
|
if (string.IsNullOrEmpty(RevData) == true) return;
|
|
if (this.ReceiveString != null) this.ReceiveString(RevData);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
ErrorFollow.TraceWrite("comm_DataReceived", ex.StackTrace, ex.Message);
|
|
}
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
|
|
#region 返回要发送的消息
|
|
public SocketMessage GetNextSocketMessage(int RefshSecond)
|
|
{
|
|
try
|
|
{
|
|
var item = ListMessage.GetNextSocketMessage(RefshSecond);
|
|
if (item == null) return null;
|
|
if (item.SendNumber > 0) DecrementWaitMsgNumber();
|
|
return item;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
ErrorFollow.TraceWrite("SerialPortService.GetNextSocketMessage", ex.StackTrace, ex.Message);
|
|
}
|
|
return null;
|
|
}
|
|
#endregion
|
|
#region 移除已发送消息
|
|
public void RemoveSocketMessage()
|
|
{
|
|
ListMessage.RemoveEmploy();
|
|
}
|
|
#endregion
|
|
|
|
#region 增加等待回复的消息数
|
|
public void IncrementWaitMsgNumber()
|
|
{
|
|
Interlocked.Increment(ref WaitMsgNumber);
|
|
}
|
|
#endregion
|
|
#region 减少等待回复的消息数
|
|
public void DecrementWaitMsgNumber()
|
|
{
|
|
Interlocked.Decrement(ref WaitMsgNumber);
|
|
}
|
|
#endregion、
|
|
#region 消除已回复消息
|
|
public SocketMessage EndWaitMsg(string SequenceID)
|
|
{
|
|
try
|
|
{
|
|
SocketMessage msg = ListMessage.CheckOut(SequenceID);
|
|
DecrementWaitMsgNumber();
|
|
return msg;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
ErrorFollow.TraceWrite("SerialPortService.IncrementWaitMsgNumber", ex.StackTrace, ex.Message);
|
|
}
|
|
return null;
|
|
}
|
|
#endregion
|
|
#region 消除已回复首行消息
|
|
public SocketMessage EndFirstMsg()
|
|
{
|
|
try
|
|
{
|
|
SocketMessage msg = ListMessage.CheckOut();
|
|
DecrementWaitMsgNumber();
|
|
return msg;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
ErrorFollow.TraceWrite("SerialPortService.EndFirstMsg", ex.StackTrace, ex.Message);
|
|
}
|
|
return null;
|
|
}
|
|
#endregion
|
|
#region 移除消息
|
|
public void RemoveMsg(string FunNo)
|
|
{
|
|
try
|
|
{
|
|
ListMessage.Remove(FunNo);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
ErrorFollow.TraceWrite("SerialPortService.RemoveMsg", ex.StackTrace, ex.Message);
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region 合并缓存数据
|
|
public void AddData(byte[] RevData, int Len)
|
|
{
|
|
if (CacheDataTime.AddSeconds(10) < DateTime.Now)
|
|
{
|
|
SocketBuffer.Clear();
|
|
}
|
|
Data = new byte[Len + SocketBuffer.Count];
|
|
for (int i = 0; i < SocketBuffer.Count; i++)
|
|
{
|
|
Data[i] = SocketBuffer[i];
|
|
}
|
|
Buffer.BlockCopy(RevData, 0, Data, SocketBuffer.Count, Len);
|
|
SocketBuffer.Clear();
|
|
}
|
|
#endregion
|
|
#region 直接发送数据
|
|
public void Send(byte[] Bytes)
|
|
{
|
|
comm.Write(Bytes, 0, Bytes.Length);
|
|
}
|
|
#endregion
|
|
#region 直接发送数据(String)
|
|
public void Send(string Data)
|
|
{
|
|
comm.Write(Data);
|
|
}
|
|
#endregion
|
|
#region 轮循消息列表
|
|
void WhileListUserSocket()
|
|
{
|
|
while (IsRun)
|
|
{
|
|
SocketMessage Msg = GetNextSocketMessage(this.RefshSecond);
|
|
try
|
|
{
|
|
if (Msg != null)
|
|
{
|
|
Msg.SendTime = DateTime.Now;
|
|
Msg.SendNumber++;
|
|
IncrementWaitMsgNumber();
|
|
if (this.MaxSendNumber > 0 && Msg.SendNumber > this.MaxSendNumber)
|
|
{
|
|
EndWaitMsg(Msg.SequenceID);
|
|
if (this.OverMaxSend != null) this.OverMaxSend(Msg);
|
|
continue;
|
|
}
|
|
comm.Write(Msg.Bytes, 0, Msg.Bytes.Length);
|
|
if (this.SendData != null) this.SendData(comm);
|
|
}
|
|
}
|
|
catch { }
|
|
AutoReset.WaitOne(500, false);
|
|
}
|
|
}
|
|
#endregion
|
|
#region 新增缓存
|
|
public void AddBuff(byte[] SrcArray, int offset)
|
|
{
|
|
for (int i = offset; i < SrcArray.Length; i++)
|
|
{
|
|
SocketBuffer.Add(SrcArray[i]);
|
|
}
|
|
CacheDataTime = DateTime.Now;
|
|
}
|
|
#endregion
|
|
|
|
}
|
|
}
|