C#串口接收回来的数据为什么不完整?在测试软件上是完整的,用代码写到程序就不完整而且也不正确!详情如下

我写了循环2次,再加最后一次的复原,一共是三次,正确来说接收到的数据只有三条,但是现在接收到的数据是

img

正确的应该是这样的,在别人写完的测试软件上是这样显示的(x,y值只是测试,所以打的不一样,主要是格式都不同,输出还很多)

img

这是我的接收代码

        void Comm_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            try
            {
                int len = serialPort.BytesToRead;
                Byte[] InputBuf = new Byte[len];
                serialPort.Read(InputBuf, 0, len);
                ASCIIEncoding encoding = new ASCIIEncoding();
                data = encoding.GetString(InputBuf);
                new Thread(SetReceiveData).Start();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "错误提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
        }
        public void SetReceiveData()
        {
            lock (this)

                Invoke(new MethodInvoker(delegate ()

                {

                    this.txtReceive.AppendText(data);

                }));

        }

这是我的发送代码

for(int i=1;i<=2;i++)
                {
                    string valuex = @""""+ini.IniReadValue("坐标值" + i, "x")+ @"""";
                    string valuey = @""""+ini.IniReadValue("坐标值" + i, "y")+ @"""";
                    string valuez = @""""+ini.IniReadValue("坐标值" + i, "z")+ @"""";
                    string valuer = @""""+ini.IniReadValue("坐标值" + i, "r")+ @"""";

                    sd = Encoding.UTF8.GetBytes(@"{""c"":""run""," + @"""x"":" + valuex + "," + @"""y"":" + valuey + "," + @"""z"":" + valuez + "," + @"""r"":" + valuer + "," + @"""v"":""322""}");
                    serialPort.Write(sd, 0, sd.Length);
                    textBox12.AppendText(valuex);
                    Thread.Sleep(10000);
                    
                }
                sd = Encoding.UTF8.GetBytes(@"{""c"":""run"",""x"":""0"",""y"":""0"",""z"":""0"",""r"":""0"",""v"":""322""}");
                serialPort.Write(sd, 0, sd.Length);

不好说明,只能举个例子你自己理解,“我们有一个水桶,有一个杯子不停向水桶里灌水,下面有龙头会不定时往外出水”
问上面杯子灌3次,下面的龙头出几次?
回答是:不知道。因为龙头不定时出水,他什么时候出水,每次出多少是未知数

你理解这个例子就明白问题原因,那就是无论微软还是其他IBM他们都不知道你杯子有多大,他并不负责跟你负责解析你写入的东西,他只是如实把你写入的字节数组按顺序传输出去(他并不保证你灌3次,他就把龙头开3次。他也许1次,也许6次)

所以你要做的事情是:自己负责解析,比如找个同样大小的杯子去接,这样的话,不管那个龙头开了几次,你总能得到3杯水

比如如果你不变协议,你需要做的事情是自己解析这个字符串,让他符合json-------当然这个过程会很复杂,你必须不停查找第一个{ 然后查找后面一个},然后试着解析json看能成功不,如果不行,就继续查找倒数第2个},直到找不到}为止,然后在切换第个{ 重复这个过程,如果能找到就输出,如果能就等待下次龙头开了继续接水后重复上述过程

这个过程会很麻烦,所以大多数情况下,我们使用更简单的方式,比如在发送阶段你发字符串前加2个回车换行,当我们收到查找到里面存在2个回车换行的时候就认为这是完整的一杯水

ps:回车换行只是最简单,最原始的一种约定。当然我们有很多更复杂的约定,这种约定就叫“协议”,比如googl protocol协议,apahce thift协议,传统工业modbus协议-----------------

不是别人Write 100个byte,你Read的时候就刚好 100个,有可能50,有可能60,需要读取几次才可能读完,所以你要自己拼接然后拆分

serialPort.Write(sd, 0, sd.Length);
serialPort.ReadTo("}")

别直接传json,发送的时候,使用byte[],然后定义好报文格式,接收到方便解析,如果接收的包不完整舍弃即可.