邓工写的一段 c# 串口接收数据的代码,感觉非常的经典,故写了注释,在此标记.
void _sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
int len, retry = 0;
byte[] rcvData = new byte[2048];
// 数据超过或等于包的长度
while (_sp.BytesToRead >= 6)
{
//读取一个字节,即包起始字节 0xFE
while (_sp.BytesToRead > 0)
{
if (Global.Head == _sp.ReadByte())
{
rcvData[0] = Global.Head;
break;
}
}
if (_sp.BytesToRead < 2)
{
return;
}
//读出包长度数据
_sp.Read(rcvData, 1, 2);
len = (rcvData[1] << 8) + rcvData[2];
//包太长
if (len > 2000)
{
return;
}
//如果数据太短,等待1s,以便确定是否数据尚未接收到
for (; retry < 100 && _sp.BytesToRead < len; retry++)
{
Thread.Sleep(10);
}
//数据太短 返回
if (_sp.BytesToRead < len)
{
return;
}
//读取数据
_sp.Read(rcvData, 3, len);
//校验数据 处理数据
if (CheckData(rcvData, len + 3))
{
rcvData[len + 2] = 0;
HandelReceivedData(rcvData);
}
}
}
{
int len, retry = 0;
byte[] rcvData = new byte[2048];
// 数据超过或等于包的长度
while (_sp.BytesToRead >= 6)
{
//读取一个字节,即包起始字节 0xFE
while (_sp.BytesToRead > 0)
{
if (Global.Head == _sp.ReadByte())
{
rcvData[0] = Global.Head;
break;
}
}
if (_sp.BytesToRead < 2)
{
return;
}
//读出包长度数据
_sp.Read(rcvData, 1, 2);
len = (rcvData[1] << 8) + rcvData[2];
//包太长
if (len > 2000)
{
return;
}
//如果数据太短,等待1s,以便确定是否数据尚未接收到
for (; retry < 100 && _sp.BytesToRead < len; retry++)
{
Thread.Sleep(10);
}
//数据太短 返回
if (_sp.BytesToRead < len)
{
return;
}
//读取数据
_sp.Read(rcvData, 3, len);
//校验数据 处理数据
if (CheckData(rcvData, len + 3))
{
rcvData[len + 2] = 0;
HandelReceivedData(rcvData);
}
}
}
对比先前我写的代码,有好几个优点,更加健壮了
//Serial Received Data
void _sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
int n = _sp.BytesToRead;
byte[] buf = new byte[n];
_sp.Read(buf, 0, n);
buffer.AddRange(buf);
while(buffer.Count > 5)
{
if(0xFE == buf[0])
{
int len = (buf[1] << 8) + buf[2];
//数据区尚未接收完整
if (buffer.Count < len)
{
break;
}
byte[] ReceiveBytes = new byte[len];
buffer.CopyTo(0, ReceiveBytes, 0, len);
if(CheckData(ReceiveBytes))
{
HandelReceivedData(ReceiveBytes);
}
buffer.RemoveRange(0, len);
}
else
{
buffer.RemoveAt(0);
}
}
}
void _sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
int n = _sp.BytesToRead;
byte[] buf = new byte[n];
_sp.Read(buf, 0, n);
buffer.AddRange(buf);
while(buffer.Count > 5)
{
if(0xFE == buf[0])
{
int len = (buf[1] << 8) + buf[2];
//数据区尚未接收完整
if (buffer.Count < len)
{
break;
}
byte[] ReceiveBytes = new byte[len];
buffer.CopyTo(0, ReceiveBytes, 0, len);
if(CheckData(ReceiveBytes))
{
HandelReceivedData(ReceiveBytes);
}
buffer.RemoveRange(0, len);
}
else
{
buffer.RemoveAt(0);
}
}
}