官方提醒4 2023-03-15 19:00 采纳率: 68.2%
浏览 39
已结题

C#中如何使判断数据的长度

我的串口工具每次读取一个字节的16进制数据 ,我想判断我读取的数据满足8个字节的时候,就传给一个变量 然后打印到textBox1上面,我该如何写


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.ToolBar;

namespace danzijie
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            comboBox1.Items.AddRange(System.IO.Ports.SerialPort.GetPortNames());
            serialPort1.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived);
        }
        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                if (serialPort1.IsOpen)
                {
                    serialPort1.Close();
                    button1.Text = "点击打开串口";
                }
                else
                {
                    serialPort1.PortName = comboBox1.Text;
                    serialPort1.Open();
                    button1.Text = "点击关闭串口";
                }
            }
            catch (Exception ex)
            {
                //捕获可能发生的异常并进行处理

                //捕获到异常,创建一个新的对象,之前的不可以再用
                serialPort1 = new System.IO.Ports.SerialPort();
                //刷新COM口选项
                comboBox1.Items.Clear();
                comboBox1.Items.AddRange(System.IO.Ports.SerialPort.GetPortNames());
                //响铃并显示异常给用户
                System.Media.SystemSounds.Beep.Play();
                button1.Text = "打开串口";
                button1.BackColor = Color.ForestGreen;
                MessageBox.Show(ex.Message);
            }

        }

        private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            string hex;
            CheckForIllegalCrossThreadCalls = false;
            byte ReceiveData;
            ReceiveData = (byte)serialPort1.ReadByte();
            string str = Convert.ToString(ReceiveData, 16).ToUpper();
            StreamWriter sw = new StreamWriter(@"C:\Users\g'x'r\Desktop\jieshou.txt", true);//写入文件夹
            if (str.Length != 2) 
            {
                str += 0;
            }
            else if (str == "68") 
            {
               if (str.Length<=8) 
               {
                    hex = str + str;
                    textBox1.Text = hex;
               }
            }            
            sw.Write(str);
            sw.Close();
        }
    }
}

  • 写回答

3条回答 默认 最新

  • wanghui0380 2023-03-16 16:44
    关注
    //不想重复去讲system.io.pipelines了,在这里讲了很多次了有些腻味了
    //就直接进行字节分割,不管你后面是不是还会碰到半包,1.5包的情况
    
    ReadOnlySequence<byte> source = new ReadOnlySequence<byte>(new byte[]{0x01,0x02,0x3,0x04});
    
    //要求简单,直接偷懒写法,不做封包协议判定,直接切割数组
    List<byte[]> temp = new List<byte[]>();
    while (source.Length>2)
    {
        temp.Add(source.Slice(source.Start,2).ToArray());
    }
    
    

    补充

    //仔细看了你代码,你想0x68开头,往后读7个对吧。
    
    ReadOnlySequence<byte> source = new ReadOnlySequence<byte>(new byte[]{0x00,0x68,0x01,0x68,0x02});
    //上面我特地加了个0x00,其实是想告诉你,串口并不是按你认为的方式工作的,也不是你说的别人的串口工具如何
    //别人的串口工具其实跟你现在写的是一模一样的,只不过他收的比你快,缓冲区没有被代码堵上
    //但是如果对方发的很快,比如20ms/次,一个通用串口工具就会显示的跟你一模一样的。因为他代码在收的再快,20ms/次的速度也来不及收,所以缓冲区就会堆积。如果想真正解决它请查system.io.pipelines的用法
    
    //因为需要判定头,所以我们就不能用偷懒的写法了,我们得用正规的方法做
    
    SequenceReader<byte> reader = new SequenceReader<byte>(source);
    var head = (new byte[] { 0x68 }).AsSpan();//头标识
    List<byte[]> res = new List<byte[]>(); //这个res就是你要结果
    while (!reader.End)
    {
        if (reader.TryAdvanceToAny(head,false)) //如果能查到头
        {
            byte[] b = new byte[2];
            if (reader.TryCopyTo(b))
            {
                res.Add(b);
    
                reader.Advance(2);//告诉reader,我从第一找到0x68处取走了2个
            }
        }
    }
    
    
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 3月27日
  • 已采纳回答 3月19日
  • 创建了问题 3月15日

悬赏问题

  • ¥15 求MCSCANX 帮助
  • ¥15 机器学习训练相关模型
  • ¥15 Todesk 远程写代码 anaconda jupyter python3
  • ¥15 我的R语言提示去除连锁不平衡时clump_data报错,图片以下所示,卡了好几天了,苦恼不知道如何解决,有人帮我看看怎么解决吗?
  • ¥15 在获取boss直聘的聊天的时候只能获取到前40条聊天数据
  • ¥20 关于URL获取的参数,无法执行二选一查询
  • ¥15 液位控制,当液位超过高限时常开触点59闭合,直到液位低于低限时,断开
  • ¥15 marlin编译错误,如何解决?
  • ¥15 VUE项目怎么运行,系统打不开
  • ¥50 pointpillars等目标检测算法怎么融合注意力机制