qq_45899507 2022-09-16 00:55 采纳率: 0%
浏览 153
已结题

请问偏移量和长度超出数组的界限以及清除缓存要怎么解决呢

串口通讯定时发送的问题,在接收的时候,第一次运行接收完全没有问题,然后停止发送又重新发送就会报“偏移量和长度超出数组的界限,或者计数大于从索引到源集合结尾处的元素数量”,且第二次定时发送后接收区变得不规律起来,添加的空格字符串也会丢失,如图

img

    /// <summary>
    /// 串口接收数据
    /// </summary>
    /// <returns></returns>

    private SerialPort sp = new SerialPort();
    public byte[] ReceiveData()
    {
        //定义一个接收数组,获取接收缓冲区数据的字节数
        byte[] byteData = new byte[this.serialPort.BytesToRead];
        //读取数据
        this.serialPort.Read(byteData, 0, serialPort.BytesToRead);

        //sp.DiscardInBuffer();

        return byteData;
    }

#region 发送数据

    private void btnSend_Click(object sender, EventArgs e)
    {
        if (this.txtSender.Text.Trim().Length == 0)
        {
            MessageBox.Show("发送内容不能为空!", "提示信息");
        }
        else
        {
            string adatetime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
            string aatime = DateTime.Now.ToString(@"ss\:fff"); //显示2位秒数和秒数后面3位
            //开始发送
            SendData(this.txtSender.Text.Trim());
        }
    }

    private void SendData(string data)
    {
        try
        {
            if (this.ckb16Send.Checked)//发送十六进制数据
            {
                this.serialPortHelper.SendData(data, SendFormat.Hex);
            }
            else  //发送字符串
            {
                this.serialPortHelper.SendData(data, SendFormat.String);
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show("发送数据出现错误:" + ex.Message, "错误提示!");
        }
    }

    #endregion

    #region 串口接收数据的事件

    /// <summary>
    /// 串口接收数据
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        try
        {
            ReceiveData(this.serialPortHelper.ReceiveData());
        }
        catch (Exception ex)
        {
            MessageBox.Show("接收数据出现错误:" + ex.Message);
        }
    }
    /// <summary>
    /// 接收数据的具体实现过程
    /// </summary>
    /// <param name="byteData"></param>
    private void ReceiveData(byte[] byteData)
    {
        string data = string.Empty;
        if (this.ckb16Receive.Checked)//十六机制接收
        {
            data = this.serialPortHelper.AlgorithmHelperObject.BytesTo16(byteData, Enum16Hex.Blank);
            //在这里编写具体的数据处理过程。。。可以保存到数据库,或其他文件...
        }
        else
        {
            data = this.serialPortHelper.AlgorithmHelperObject.BytesToString(byteData, Enum16Hex.None);
        }

        //显示到当前文本框中
        //因为接收数据的事件是一个独立显存,所有必须通过跨线程访问可视化控件的方法来完成展示
        //Invoke()方法的第一个参数必须是返回值为void的委托,第二个参数是给委托对应方法传递的参数
        this.txtReceiver.Invoke(new Action<string>(s => { this.txtReceiver.Text += "   " + s; }), data);

    }

    #endregion
偏移量和长度超出数组的界限,或者计数大于从索引到源集合结尾处的元素数量
猜测是缓存区的问题,想用DiscardInBuffer()方法清除一下缓存,但用了DiscardInBuffer()方法后接收的时候会再“报端口被关闭”的错误,如上方被注释掉的sp.DiscardInBuffer();
请问这种问题是什么原因导致的,怎么才能解决呢

展开全部

  • 写回答

2条回答 默认 最新

  • 赵4老师 2022-09-16 02:30
    关注

    不要动态申请释放接收缓冲区
    使用全局静态缓冲区或程序初始化时申请一个足够大的缓冲区

    评论
  • wanghui0380 2022-09-16 02:59
    关注

    弹框是你弹框的,这个东西你应该写在try catch里面,至少你发的代码不存在try,我们无法确定真正的问题就发生在你贴的代码处
    所以,你应该给我们try catch那里的代码,而不是这里的代码。(或者说,你应该给我们异常的详细信息)

    从你后续补充说明,一会第一次,一会第2次。我个人认为,大概率你是认为接收的都是固定长度,但是实际情况是串口接收你是从缓冲区取,他本来不是固定长度
    也许你不理解,我们可以打个比方。比如目前的丰巢快递柜,串口那块就是快递员,他如实把货物给你送过来。(但他不关心你这个是一单还是几单,他只是如实给你送过来),然后你去丰巢取(缓冲区)你现在还认为,他一定是按固定长度,或者一单就是一格么?

    评论 编辑记录
编辑
预览

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 9月19日
  • 修改了问题 9月16日
  • 创建了问题 9月16日
手机看
程序员都在用的中文IT技术交流社区

程序员都在用的中文IT技术交流社区

专业的中文 IT 技术社区,与千万技术人共成长

专业的中文 IT 技术社区,与千万技术人共成长

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

客服 返回
顶部