我正在处理来电显示的串行设备并编写以下程序:
serialPort = new SerialPort("COM7", 19200, Parity.None, 8, StopBits.One);
serialPort.DataReceived += serialPort_DataReceived;
serialPort.RtsEnable = true;
serialPort.Encoding = Encoding.ASCII;
serialPort.Open();
void serialPort_DataReceived(object s, SerialDataReceivedEventArgs e)
{
byte[] data = new byte[serialPort.BytesToRead];
serialPort.Read(data, 0, data.Length);
Console.WriteLine(Encoding.ASCII.GetString(data));
}
首先我接到一个电话,事件会完美触发,结果是:"A0101181456926E"
问题是随后的事件......下次我打电话时,事件serialPort_DataReceived
每次都会激活很多次1个字符。
是否有要设置的属性或调用方法来解决此问题?
PS。如果我对该行serialPort.RtsEnable = true;
发表评论,我不会收到任何后续事件。
答案 0 :(得分:5)
正如Henk所提到的,您可以设置在使用属性DataReceived
触发ReceivedBytesThreshold
事件之前接收的字节数。
但无论如何,你必须处理一次接收的任意数量的字节。您必须以能够在完全接收消息时识别的方式设计协议。
答案 1 :(得分:3)
这是正常行为。您可以更改ReceivedBytesThreshold属性,但这样做意味着您必须至少接收该数量,如果传输中有任何错误,再次进行同步可能会很困难。
我的建议是将ReceivedBytesThreshold = 1,并将收到的数据排队,直到得到你需要的为止。
答案 2 :(得分:0)
我已经完成了通过构建缓冲机制来检测我何时收到基于供应商协议的完整输入字符串的建议。工作良好。 (必须说,并非所有协议设计都提供了明确的开始和结束序列)我无法理解为什么DataReceived事件处理程序仍在触发,尽管我使用Port.ReadExisting()方法读取输入缓冲区时,字符串长度为零。读取https://msdn.microsoft.com/en-us/library/system.io.ports.serialport.receivedbytesthreshold(v=vs.110).aspx上的SerialPort.ReceivedBytesThreshold属性我意识到即使属性的默认值为1,处理程序仍将触发"如果收到Eof字符,则无论字节数是多少内部输入缓冲区"也许这就是处理程序激发看似不必要的原因
的原因