SerialPort缓冲区

SerialPort缓冲区中有:接收缓冲区,发送缓冲区,输入缓冲区,输出缓冲区,传输缓冲区。

例如:

串口属性:BytesToRead(获取接收缓冲区中数据的字节数)--这里提到的是“接收缓冲区”

串口属性:ReadBufferSize(获取或设置 System.IO.Ports.SerialPort 输入缓冲区的大小)---这里提到的是“输入缓冲区”

串口属性:BytesToWrite(获取发送缓冲区中数据的字节数)---这里提到的是“发送缓冲区”

串口属性:WriteBufferSize(获取或设置串行端口输出缓冲区的大小)---这里提到的是“输出缓冲区”

串口属性:DiscardOutBuffer(丢弃来自串行驱动程序的传输缓冲区的数据)---这里提到的是“传输缓冲区”

串口没这么复杂。

收发在最底层是通过2个顺序表模拟的循环队列实现的,你能设置这个队列的长度,我们常用的是2048或4096,2048足够用,4096是正好内存一页长度,分配一整张页表。

不过这都扯远了。.net下使用SerialPort你可以忽略这些。那些系统的缓冲区存在的目的是将流数据缓存下来,因为串口作为一种流设备,硬件,驱动层实际上是逐个字节发送的,但你的应用软件这么做却很麻烦,那么及时的处理串口收发也不现实,所以,操作系统创建一个缓冲区,用于将你写串口的数据缓存起来,例如你调用写串口后,系统将你传递的数据复制到发送队列,排队发送,并立刻返回避免你的软件卡住。接受部分,则是在你的软件调用Read方法之前,如果有数据来,系统将数据保存在接收的队列中,当你调用Read时,一次性将缓存数据读出给你,并清空缓存。

并没有那么多的缓存,你看系统的丢弃缓存功能,也只有in和out。(DiscardInBuffer/DiscardOutBuffer)

因为串口的流特性,缓冲区内存储了多少数据是动态变化的,你可以通过BytesToRead属性获取当前的有效字节数。

接收缓冲区与输入缓冲区的区别可能想表达的就是BytesToRead是有效数据长度,ReadBufferSize表示接收队列的长度。BytesToRead总小于或等于ReadBufferSize。

写和读一样理解。

DiscardOutBuffer的意思是将正在发送的队列中数据清空。

另外,我上面描述的未必就是底层真实的行为,只是大概,因为串口的驱动是可以自己写,自己实现的,大概原理是这样,但也不排除有人实现串口驱动时自己创造几个队列来分别存储以上你描述的内容,这个只和具体驱动实现有关。

而我们的.net/api的意义就是让你忽略这些细节,只理解接口意义,串口流设备的意义。

 
0
原文地址:https://www.cnblogs.com/qqhfeng/p/6649348.html