C#和SerialPort类截断数据

时间:2012-01-19 16:24:16

标签: c# .net serial-port

我有一个使用.NET SerialPort类的C#应用​​程序。我用来从串口接收数据的代码没什么特别的。关键部分是

//Open the port
            comport.BaudRate = myPort.BaudRate;
            comport.StopBits = StopBits.One;
            comport.DataBits = 8;
            comport.Parity = Parity.None;
            comport.ReadTimeout = 20000;


            comport.PortName = myPort.PortSystemName;
            comport.Handshake = Handshake.None;
            comport.RtsEnable = true;


            comport.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
comport.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);

    private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {

            string msg = "";
            try
            {
                msg = comport.ReadExisting();

                if (comport.IsOpen)
                    comport.Close();
         }

此代码在Windows XP中非常正常。但是,在Windows 7上,无论发送什么数据,它都会遇到问题,它只会获取前四个字符。所以在像“123456”这样的字符串中,msg将是“1234”。收集数据的设备是RFIdeas pcProx,我已经验证数据很好。我还验证了数据在超级终端中看起来没问题。因此,我在代码中获取数据的方式有些奇怪。救命啊!

1 个答案:

答案 0 :(得分:5)

这与API完全一致。它不是,也从来没有保证会读到所有内容:

  

此方法以字符串形式返回SerialPort对象的流和内部缓冲区的内容。此方法不使用超时。请注意,此方法可以在内部缓冲区中留下尾随前导字节,这会使BytesToRead值大于零。

此外,您需要处理“尚未在内部缓冲区中” - 您不只是在BytesToRead为正时读取。这通常涉及循环和缓冲,直到收到整个消息。

您的工作是通过使用诸如行尾之类的标记或使用长度前缀标题来读取正确数量的数据。

如果它在XP上运行得非常好,那么这只是好运(也许是通过一些时间和/或效率调整)。

以上所有内容同样适用于大多数输入,而不仅仅是串行端口;例如,文件IO和网络IO的工作原理完全相同。