所以我从串口读取数据,到目前为止一直很好,但来自串口的数据是分块的,我的协议规定每条消息都以SOH(\ u0001字节)开头并结束使用EOT(\ u0004),我尝试按SOH
字节拆分消息,但仍然存在问题。
有一种更优雅,更安全的方法吗?
private void RecebendoDados(object sender, SerialDataReceivedEventArgs e)
{
try
{
var id_prova = Form1._Form1.IDPROVA;
var serie = Form1._Form1.SERIE;
var fase = Form1._Form1.FASE;
var http = new ComunicacaoWeb();
var sp = (SerialPort)sender;
var indata = sp.ReadExisting();
Console.WriteLine(indata+"\n\r");
if (!sp.IsOpen) {
sp.Open();
}
var pacotes = indata.Split(new[] { "\u0004" }, StringSplitOptions.None);
答案 0 :(得分:0)
<强> 1 强>
这是一种更强大,更优雅,更安全的方法吗?
如果您的消息以EOT控制代码结束,则SerialPort
允许您准确读取此char的第一个匹配项。
SerialPort sp = (SerialPort)sender;
// this lines converts the hex-code of EOT to a char and read the incoming
// message only up to this point
string indata = sp.ReadTo(Convert.ToChar(0x04));
现在你只需要摆脱SOT:
indata = indata.TrimStart(Convert.ToChar(0x01));
此时你应该有干净的信息。
属性BytesToRead
将告诉您缓冲区中是否还有数据:
int stillToBeRead = sp.BytesToRead;
如有必要,您可以检查并重复阅读程序。
<强> 2 强>
这是一种更加优雅和安全的方式吗?
如果您尝试从已关闭的端口读取,则它将失败并显示System.InvalidOperationException
。通过这种逻辑,永远不会输入代码中的if条件来重新打开端口。
var sp = (SerialPort)sender;
var indata = sp.ReadExisting();
if (!sp.IsOpen) {
// this will never be executed
sp.Open();
}
你应该检查端口是否打开,并且在尝试读取之前有数据要读取。我猜RecebendoDados
是DataReceived
事件,所以关闭端口和没有数据读取的概率很低,但仍然是:魔鬼睡在细节中;)