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 m_SocketBuffer = new List(); /// /// 网络数据缓存 /// public List 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; /// /// 最大消息等待回包数量(滑动窗口) /// 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"; /// /// 读取数据的方式(0 byte方式读取1按回车读取 /// 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 ReceiveData; public event Action SendData; public event Action ReceiveString; /// /// 超出最大发送次数 /// public event Action 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 } }