废话少说,直接上干货。感兴趣的读者自己去研究代码吧。请见谅。

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串口通信发送接收,处理接收数据完整

[转]C# SerialPort串口通信发送接收,处理接收数据完整的更多相关文章

  1. System.IO.Ports.SerialPort串口通信接收完整数据

    C#中使用System.IO.Ports.SerialPort进行串口通信网上资料也很多,但都没有提及一些细节: 比如 串口有时候并不会一次性把你想要的数据全部传输给你,可能会分为1次,2次,3次分别 ...

  2. winform SerialPort串口通信问题

    一.串口通信简介串行接口(串口)是一种可以将接受来自CPU的并行数据字符转换为连续的串行数据流发送出去,同时可将接受的串行数据流转换为并行的数据字符供给CPU的器件.一般完成这种功能的电路,我们称为串 ...

  3. Linux串口通信中一种接收不到数据的问题的解决

    转载来源:嵌入式系统之初学者点滴 (百度空间) 原文 在这篇文章()中,实现了Linux环境下的串口读写操作,程序也运行成功了.但是再进一步测试时发现,如果开机之后直接如上文中所说,分别运行读程序和写 ...

  4. C#串口通信发送数据

    1 发送数据 需要2个串口 http://www.openedv.com/thread-228847-1-1.html 下载源文件 File_Protocol_Test.rar

  5. ESP32 BLE蓝牙 微信小程序通信发送大于20字符数据

    由于微信小程序只支持BLE每次发送数据不大于20个字节,ESP32则有经典蓝牙.低功耗蓝牙两种模式. 要解决发送数据大于20个字节的问题,最简单实用的方式就是分包发送.如下图所示: 1.什么起始字符和 ...

  6. Qt 串口通信

    在Qt5之前,串口通信基本依赖于第三方库,下面是我曾接触过的串口通信类库: 名称 语言 平台   QextSerialPort QT C++ Win/Linux http://sourceforge. ...

  7. Linux与Windows串口通信

    串口是常用的计算机与外部串行设备之间的数据传输通道,由于串行通信方便易行,所以应用广泛.现在国际上不断有串口新技术及新规格推出,结合社会各方面需要,串口通信发展的空间庞大.串口通讯技术因其自身的优势和 ...

  8. 在C#中实现串口通信的方法

    通常,在C#中实现串口通信,我们有四种方法: 第一:通过MSCOMM控件这是最简单的,最方便的方法.可功能上很难做到控制自如,同时这个控件并不是系统本身所带,所以还得注册,不在本文讨论范围.可以访问h ...

  9. c#中实现串口通信的几种方法

    c#中实现串口通信的几种方法 通常,在C#中实现串口通信,我们有四种方法: 第一:通过MSCOMM控件这是最简单的,最方便的方法.可功能上很难做到控制自如,同时这个控件并不是系统本身所带,所以还得注册 ...

  10. C#串口通信—向串口发送数据,同步接收返回数据

    最近写C#串口通信程序,系统是B/S架构.SerialPort类有一个DataReceived事件,用来接收串口返回的数据,但这种方式在C/S架构下很好用,但B/S就不好处理了.所以写了一个同步模式接 ...

随机推荐

  1. Linux环境下的mysql安装

    MySQL8.0.26-Linux版安装 1.准备一台Linux服务器 云服务器或者虚拟机都可以; Linux的版本为 Centos7; 2.下载Linux版MySQL安装包 https://down ...

  2. Elasticsearch倒排索引结构【转载】

    一切设计都是为了提高搜索的性能 倒排索引(Inverted Index)也叫反向索引,有反向索引必有正向索引.通俗地来讲,正向索引是通过key找value,反向索引则是通过value找key. 先来回 ...

  3. Greenplum 通过外部表快速导入数据

    通过Greenplum外部表可以快速导入数据 create external table "public"."ext_tablename" ( like &qu ...

  4. Linux再学!

    第三篇Linux入门 一.linux基本指令 1.Linux根目录为/,后续路径用/分隔,如/home/admin 2.Linux命令 基础格式: command: 命令本身 -options:[可选 ...

  5. KVM的基本使用

    1. 虚拟化介绍 虚拟化是云计算的基础.简单的说,虚拟化使得在一台物理的服务器上可以跑多台虚拟机,虚拟机共享物理机的 CPU.内存.IO 硬件资源,但逻辑上虚拟机之间是相互隔离的. 物理机我们一般称为 ...

  6. cmu15545笔记-Join算法(Join Algorithms)

    目录 Overview Nested Loop Join Naïve Block Index Sort-Merge Join Hash Join Simple Hash Join Partition ...

  7. php 如何实现 git diff

    无意间想到这个问题,如何用php来实现git diff,如果实现了这个功能,岂不是能够使用php对在线编辑文件的功能做更进一步的优化和提升? 查了一下还真有这样的库,话不多说,开始执行 compose ...

  8. Think in Java之构造器的真正调用顺序

    构造器是OOP的重要组成部分,很多人认为它很容易.只不过是new了一个对象而已.而think in java的作者却告诉我们,其实这并不容易.先看下面这个例子.在你没看结果之前,你觉得你的答案是对的么 ...

  9. SAX,DOM,JAXP,JDOM,DOM4J比较分析

    第一:首先介绍一下SAX,DOM,JAXP,JDOM,DOM4J的基本知识:(注意:至于 JAXP JAXB JAXM JAXR JAX-RPC 分别指什么,查看http://gceclub.sun. ...

  10. confd+Nacos实现nginx配置文件管理

    场景: 由于公司内部站点保护的需求, 将部分的站点添加白名单, 这边的操作是在nginx配置文件中添加如下代码 allow 127.0.0.1: deny all; 但随之问题也出现了, 需要添加一个 ...