C#和SerialPort类截断数据
我有一个使用.NET SerialPort类的C#应用程序。我用来从串口获取数据的代码没有什么特别之处。关键部分是C#和SerialPort类截断数据,c#,.net,serial-port,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;
//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中运行得非常好。然而,在Windows7上,它遇到了这样的问题:无论发送什么数据,它都只接收前四个字符。因此,在类似“123456”的字符串中,msg将是“1234”。收集数据的设备是RFPCProx,我已经验证了数据是否正常。我还验证了数据在超级终端中看起来正常。因此,我在代码中提取数据的方式肯定有些奇怪。救命啊 这与API完全一致。它不是,也从来没有保证阅读所有内容: 此方法以字符串形式返回SerialPort对象的流和内部缓冲区的内容。此方法不使用超时。请注意,此方法可以在内部缓冲区中保留尾随的前导字节,这使得BytesToRead值大于零 此外,您还需要处理“尚未在内部缓冲区中”的问题—您不能只在BytesToRead为正值时读取。这通常涉及循环和缓冲,直到接收到整个消息 您的工作是通过使用诸如线端点之类的标记或使用长度前缀标题来读取正确数量的数据 如果它在XP上运行得非常好,那么这仅仅是一个好运气(可能是通过一些时间和/或效率调整)
以上所有内容同样适用于大多数输入,而不仅仅是串行端口;例如,文件IO和网络IO的工作原理几乎完全相同。旁注:我发现即使代码相同,
SerialPort
在表单/控件中托管与手动创建时,其行为也会有所不同。因此,您建议使用类似于循环的方法,将bytestoread检查为零?或者,从代码的角度来看,你到底有什么建议?@Jim我不会过多地关注BytesToRead,因为这只是告诉你什么是可用的,并不是说没有更多的数据。如果可能,我将使用ReadLine(),并使用新行分隔数据。如果不能使用ReadLine(),则是:需要循环。但是:知道何时拥有所有数据是由协议定义的。如果没有一些定义(例如,长度前缀或换行符终止),就无法区分“1234”和“12345”之间的区别,但5仍然是传入的,尚未到达,因此只有1234可用“好,足够公平”。我想我可以设置我的设备发送比任何可能的数据都长的固定长度字符串,这样我就可以键入字符串的长度。