[轉]C# SerialPort串口通信發送接收,處理接收數據完整


廢話少說,直接上干貨。感興趣的讀者自己去研究代碼吧。請見諒。

using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;

namespace SerialPortCom
{
    public class SerialPortComImplement
    {
        public delegate void RecEventHandler(byte[] queueByte);
        public event RecEventHandler DataReceivedEvent;
        private SerialPort serialPort;
        private List<byte> buffer = new List<byte>(4096);
        /// <summary>
        /// 初始化
        /// </summary>
        /// <param name="portName">端口名稱</param>
        /// <param name="baudRate">波特率</param>
        /// <param name="dataBits">數據位</param>
        public SerialPortComImplement(string portName, int baudRate, int dataBits)
        {
            serialPort = new SerialPort(portName, baudRate, Parity.None);
            serialPort.DataBits = dataBits;
            serialPort.StopBits = StopBits.One;
            serialPort.ReadTimeout = 2000;
            serialPort.WriteBufferSize = 1024;
            serialPort.ReadBufferSize = 1024;
            serialPort.RtsEnable = true;
            serialPort.DtrEnable = true;
            serialPort.ReceivedBytesThreshold = 1;
            serialPort.DataReceived += new SerialDataReceivedEventHandler(serialPort_DataReceivedEventHandler);
        }
        /// <summary>
        /// 串口數據接收事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void serialPort_DataReceivedEventHandler(object sender, SerialDataReceivedEventArgs e)
        {
            try
            {
                byte[] readBuffer = null;
                int n = serialPort.BytesToRead;
                byte[] buf = new byte[n];
                serialPort.Read(buf, 0, n);
                //1.緩存數據           
                buffer.AddRange(buf);
                //2.完整性判斷         
                while (buffer.Count >= 7)
                {
                    //至少包含標頭(1字節),長度(1字節),校驗位(2字節)等等
                    //2.1 查找數據標記頭            
                    if (buffer[0] ==  0x00) //傳輸數據有幀頭,用於判斷       
                    {
                        int len = buffer[1];
                        if (buffer.Count < len + 2)
                        {
                            //數據未接收完整跳出循環
                            break;
                        }
                        readBuffer = new byte[len + 2];
                        //得到完整的數據,復制到readBuffer中    
                        buffer.CopyTo(0, readBuffer, 0, len + 2);
                        //從緩沖區中清除
                        buffer.RemoveRange(0, len + 2);
                        
                  
                        //觸發外部處理接收消息事件
                            
                        }
                    }
                    else //開始標記或版本號不正確時清除           
                    {
                        buffer.RemoveAt(0);
                    }
                }
            }
            catch (Exception ex)
            {
                SerialPortLog.Error(ex, "");
            }
        }
        /// <summary>
        /// 打開端口
        /// </summary>
        public bool Open()
        {
            try
            {
                if (!serialPort.IsOpen)
                {
                    serialPort.Open();
                    return true;
                }
                else
                {
                    return true;
                }
            }
            catch (Exception ex)
            {
                SerialPortLog.Error(ex, "");
                return false;
            }

        }
        /// <summary>
        /// 發送字節
        /// </summary>
        /// <param name="writeBytes">要發送的字節</param>
        /// <returns></returns>
        public bool Write(byte[] writeBytes)
        {
            if (Open())
            {
                try
                {
                    serialPort.Write(writeBytes, 0, writeBytes.Length);
                    string mergeStr = "發送:";
                    for (int j = 0; j < writeBytes.Length; j++)
                    {
                        mergeStr = mergeStr + writeBytes[j].ToString("x") + " ";
                    }
                    SerialPortLog.Info(mergeStr);
                    return true;
                }
                catch (Exception ex)
                {
                    SerialPortLog.Error(ex, "");
                    return false;
                }
            }
            return false;
        }
        /// <summary>
        /// 發送字符串
        /// </summary>
        /// <param name="writestrs"></param>
        /// <returns></returns>
        public bool Write(string writeStrs)
        {
            if (Open())
            {
                try
                {
                    serialPort.Write(writeStrs);
                    Thread.Sleep(100);
                    return true;
                }
                catch
                {
                    return false;
                }
            }
            return false;
        }
        /// <summary>
        /// 讀取數據
        /// </summary>
        /// <param name="NumBytes">讀取的字節數</param>
        /// <returns></returns>
        public byte[] Read(int NumBytes)
        {
            byte[] inbuffer = null;

            if (serialPort.IsOpen && serialPort.BytesToRead > 0)
            {
                if (NumBytes > serialPort.BytesToRead)
                {
                    NumBytes = serialPort.BytesToRead;
                }
                try
                {
                    inbuffer = new byte[NumBytes];
                    int count = serialPort.Read(inbuffer, 0, NumBytes);
                }
                catch (TimeoutException timeoutEx)
                {
                    //超時異常
                    SerialPortLog.Error(timeoutEx, "");
                }
            }
            return inbuffer;
        }
        public byte[] Read()
        {
            return Read(serialPort.BytesToRead);
        }
        public string ReadLine()
        {
            try
            {
                if (serialPort.IsOpen && serialPort.BytesToRead > 0)
                {
                    string s = serialPort.ReadExisting();
                    return serialPort.ReadLine();
                }
                return null;
            }
            catch (TimeoutException timeoutEx)
            {
                SerialPortLog.Error(timeoutEx, "");
                return timeoutEx.Message;
            }
        }
        /// <summary>
        /// 關閉串口
        /// </summary>
        public void Close()
        {
            try
            {
                if (serialPort.IsOpen)
                {
                    serialPort.Close();
                }
            }
            catch (Exception ex)
            {
                SerialPortLog.Error(ex, "");
            }
        }

        public bool IsOpen
        {
            get
            {
                return serialPort.IsOpen;
            }
        }
    }
}

原文鏈接:

using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;

namespace SerialPortCom
{
    public class SerialPortComImplement
    {
        public delegate void RecEventHandler(byte[] queueByte);
        public event RecEventHandler DataReceivedEvent;
        private SerialPort serialPort;
        private List<byte> buffer = new List<byte>(4096);
        /// <summary>
        /// 初始化
        /// </summary>
        /// <param name="portName">端口名稱</param>
        /// <param name="baudRate">波特率</param>
        /// <param name="dataBits">數據位</param>
        public SerialPortComImplement(string portName, int baudRate, int dataBits)
        {
            serialPort = new SerialPort(portName, baudRate, Parity.None);
            serialPort.DataBits = dataBits;
            serialPort.StopBits = StopBits.One;
            serialPort.ReadTimeout = 2000;
            serialPort.WriteBufferSize = 1024;
            serialPort.ReadBufferSize = 1024;
            serialPort.RtsEnable = true;
            serialPort.DtrEnable = true;
            serialPort.ReceivedBytesThreshold = 1;
            serialPort.DataReceived += new SerialDataReceivedEventHandler(serialPort_DataReceivedEventHandler);
        }
        /// <summary>
        /// 串口數據接收事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void serialPort_DataReceivedEventHandler(object sender, SerialDataReceivedEventArgs e)
        {
            try
            {
                byte[] readBuffer = null;
                int n = serialPort.BytesToRead;
                byte[] buf = new byte[n];
                serialPort.Read(buf, 0, n);
                //1.緩存數據           
                buffer.AddRange(buf);
                //2.完整性判斷         
                while (buffer.Count >= 7)
                {
                    //至少包含標頭(1字節),長度(1字節),校驗位(2字節)等等
                    //2.1 查找數據標記頭            
                    if (buffer[0] ==  0x00) //傳輸數據有幀頭,用於判斷       
                    {
                        int len = buffer[1];
                        if (buffer.Count < len + 2)
                        {
                            //數據未接收完整跳出循環
                            break;
                        }
                        readBuffer = new byte[len + 2];
                        //得到完整的數據,復制到readBuffer中    
                        buffer.CopyTo(0, readBuffer, 0, len + 2);
                        //從緩沖區中清除
                        buffer.RemoveRange(0, len + 2);
                        
                  
                        //觸發外部處理接收消息事件
                            
                        }
                    }
                    else //開始標記或版本號不正確時清除           
                    {
                        buffer.RemoveAt(0);
                    }
                }
            }
            catch (Exception ex)
            {
                SerialPortLog.Error(ex, "");
            }
        }
        /// <summary>
        /// 打開端口
        /// </summary>
        public bool Open()
        {

            try
            {
                if (!serialPort.IsOpen)
                {
                    serialPort.Open();
                    return true;
                }
                else
                {
                    return true;
                }
            }
            catch (Exception ex)
            {
                SerialPortLog.Error(ex, "");
                return false;
            }

        }
        /// <summary>
        /// 發送字節
        /// </summary>
        /// <param name="writeBytes">要發送的字節</param>
        /// <returns></returns>
        public bool Write(byte[] writeBytes)
        {
            if (Open())
            {
                try
                {
                    serialPort.Write(writeBytes, 0, writeBytes.Length);
                    string mergeStr = "發送:";
                    for (int j = 0; j < writeBytes.Length; j++)
                    {
                        mergeStr = mergeStr + writeBytes[j].ToString("x") + " ";
                    }
                    SerialPortLog.Info(mergeStr);
                    return true;
                }
                catch (Exception ex)
                {
                    SerialPortLog.Error(ex, "");
                    return false;
                }
            }
            return false;
        }
        /// <summary>
        /// 發送字符串
        /// </summary>
        /// <param name="writestrs"></param>
        /// <returns></returns>
        public bool Write(string writeStrs)
        {
            if (Open())
            {
                try
                {
                    serialPort.Write(writeStrs);
                    Thread.Sleep(100);
                    return true;
                }
                catch
                {
                    return false;
                }
            }
            return false;
        }
        /// <summary>
        /// 讀取數據
        /// </summary>
        /// <param name="NumBytes">讀取的字節數</param>
        /// <returns></returns>
        public byte[] Read(int NumBytes)
        {
            byte[] inbuffer = null;

            if (serialPort.IsOpen && serialPort.BytesToRead > 0)
            {
                if (NumBytes > serialPort.BytesToRead)
                {
                    NumBytes = serialPort.BytesToRead;
                }
                try
                {
                    inbuffer = new byte[NumBytes];
                    int count = serialPort.Read(inbuffer, 0, NumBytes);
                }
                catch (TimeoutException timeoutEx)
                {
                    //超時異常
                    SerialPortLog.Error(timeoutEx, "");
                }
            }
            return inbuffer;
        }
        public byte[] Read()
        {
            return Read(serialPort.BytesToRead);
        }
        public string ReadLine()
        {
            try
            {
                if (serialPort.IsOpen && serialPort.BytesToRead > 0)
                {
                    string s = serialPort.ReadExisting();
                    return serialPort.ReadLine();
                }
                return null;
            }
            catch (TimeoutException timeoutEx)
            {
                SerialPortLog.Error(timeoutEx, "");
                return timeoutEx.Message;
            }
        }
        /// <summary>
        /// 關閉串口
        /// </summary>
        public void Close()
        {
            try
            {
                if (serialPort.IsOpen)
                {
                    serialPort.Close();
                }
            }
            catch (Exception ex)
            {
                SerialPortLog.Error(ex, "");
            }
        }

        public bool IsOpen
        {
            get
            {
                return serialPort.IsOpen;
            }
        }
    }
}

------------恢復內容開始------------

廢話少說,直接上干貨。感興趣的讀者自己去研究代碼吧。請見諒。

using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;

namespace SerialPortCom
{
    public class SerialPortComImplement
    {
        public delegate void RecEventHandler(byte[] queueByte);
        public event RecEventHandler DataReceivedEvent;
        private SerialPort serialPort;
        private List<byte> buffer = new List<byte>(4096);
        /// <summary>
        /// 初始化
        /// </summary>
        /// <param name="portName">端口名稱</param>
        /// <param name="baudRate">波特率</param>
        /// <param name="dataBits">數據位</param>
        public SerialPortComImplement(string portName, int baudRate, int dataBits)
        {
            serialPort = new SerialPort(portName, baudRate, Parity.None);
            serialPort.DataBits = dataBits;
            serialPort.StopBits = StopBits.One;
            serialPort.ReadTimeout = 2000;
            serialPort.WriteBufferSize = 1024;
            serialPort.ReadBufferSize = 1024;
            serialPort.RtsEnable = true;
            serialPort.DtrEnable = true;
            serialPort.ReceivedBytesThreshold = 1;
            serialPort.DataReceived += new SerialDataReceivedEventHandler(serialPort_DataReceivedEventHandler);
        }
        /// <summary>
        /// 串口數據接收事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void serialPort_DataReceivedEventHandler(object sender, SerialDataReceivedEventArgs e)
        {
            try
            {
                byte[] readBuffer = null;
                int n = serialPort.BytesToRead;
                byte[] buf = new byte[n];
                serialPort.Read(buf, 0, n);
                //1.緩存數據           
                buffer.AddRange(buf);
                //2.完整性判斷         
                while (buffer.Count >= 7)
                {
                    //至少包含標頭(1字節),長度(1字節),校驗位(2字節)等等
                    //2.1 查找數據標記頭            
                    if (buffer[0] ==  0x00) //傳輸數據有幀頭,用於判斷       
                    {
                        int len = buffer[1];
                        if (buffer.Count < len + 2)
                        {
                            //數據未接收完整跳出循環
                            break;
                        }
                        readBuffer = new byte[len + 2];
                        //得到完整的數據,復制到readBuffer中    
                        buffer.CopyTo(0, readBuffer, 0, len + 2);
                        //從緩沖區中清除
                        buffer.RemoveRange(0, len + 2);
                        
                  
                        //觸發外部處理接收消息事件
                            
                        }
                    }
                    else //開始標記或版本號不正確時清除           
                    {
                        buffer.RemoveAt(0);
                    }
                }
            }
            catch (Exception ex)
            {
                SerialPortLog.Error(ex, "");
            }
        }
        /// <summary>
        /// 打開端口
        /// </summary>
        public bool Open()
        {
            try
            {
                if (!serialPort.IsOpen)
                {
                    serialPort.Open();
                    return true;
                }
                else
                {
                    return true;
                }
            }
            catch (Exception ex)
            {
                SerialPortLog.Error(ex, "");
                return false;
            }

        }
        /// <summary>
        /// 發送字節
        /// </summary>
        /// <param name="writeBytes">要發送的字節</param>
        /// <returns></returns>
        public bool Write(byte[] writeBytes)
        {
            if (Open())
            {
                try
                {
                    serialPort.Write(writeBytes, 0, writeBytes.Length);
                    string mergeStr = "發送:";
                    for (int j = 0; j < writeBytes.Length; j++)
                    {
                        mergeStr = mergeStr + writeBytes[j].ToString("x") + " ";
                    }
                    SerialPortLog.Info(mergeStr);
                    return true;
                }
                catch (Exception ex)
                {
                    SerialPortLog.Error(ex, "");
                    return false;
                }
            }
            return false;
        }
        /// <summary>
        /// 發送字符串
        /// </summary>
        /// <param name="writestrs"></param>
        /// <returns></returns>
        public bool Write(string writeStrs)
        {
            if (Open())
            {
                try
                {
                    serialPort.Write(writeStrs);
                    Thread.Sleep(100);
                    return true;
                }
                catch
                {
                    return false;
                }
            }
            return false;
        }
        /// <summary>
        /// 讀取數據
        /// </summary>
        /// <param name="NumBytes">讀取的字節數</param>
        /// <returns></returns>
        public byte[] Read(int NumBytes)
        {
            byte[] inbuffer = null;

            if (serialPort.IsOpen && serialPort.BytesToRead > 0)
            {
                if (NumBytes > serialPort.BytesToRead)
                {
                    NumBytes = serialPort.BytesToRead;
                }
                try
                {
                    inbuffer = new byte[NumBytes];
                    int count = serialPort.Read(inbuffer, 0, NumBytes);
                }
                catch (TimeoutException timeoutEx)
                {
                    //超時異常
                    SerialPortLog.Error(timeoutEx, "");
                }
            }
            return inbuffer;
        }
        public byte[] Read()
        {
            return Read(serialPort.BytesToRead);
        }
        public string ReadLine()
        {
            try
            {
                if (serialPort.IsOpen && serialPort.BytesToRead > 0)
                {
                    string s = serialPort.ReadExisting();
                    return serialPort.ReadLine();
                }
                return null;
            }
            catch (TimeoutException timeoutEx)
            {
                SerialPortLog.Error(timeoutEx, "");
                return timeoutEx.Message;
            }
        }
        /// <summary>
        /// 關閉串口
        /// </summary>
        public void Close()
        {
            try
            {
                if (serialPort.IsOpen)
                {
                    serialPort.Close();
                }
            }
            catch (Exception ex)
            {
                SerialPortLog.Error(ex, "");
            }
        }

        public bool IsOpen
        {
            get
            {
                return serialPort.IsOpen;
            }
        }
    }
}

原文鏈接:C# SerialPort串口通信發送接收,處理接收數據完整


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM