对于面向字节流的协议,如串口通信、TCP,数据解析方法简介如下(以串口为例):
读取串口:
BYTE readBuf[BUF_SIZE];
DWORD dwRead;
DWORD dwWantRead = BUF_SIZE;
DWORD dwResolveSuccess = 0;
while (pctcb->bStartCheck)
{
dwRead = 0;
if (ReadFile(hComm, readBuf + dwResolveSuccess, dwWantRead, &dwRead, NULL))
{
dwResolveSuccess = ResolveData(readBuf, dwResolveSuccess + dwRead);
dwWantRead = BUF_SIZE - dwResolveSuccess;
}
else
{
ShowSystemError(pctcb->hwnd, GetLastError());
break;
}
}
CloseHandle(hComm);
假设要从中解析出这5路数据:
//PPG和ECG组成一帧
//BYTE ppg_ecg[18] = { 0x40, 0x40, 0x00, 0x00, 0x0A, 0xD1, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0xFF, 0x23, 0x23 };
//BYTE temp1_data[11] = { 0x40, 0x40, 0x00, 0x00, 0x03, 0xD2, 0x01, 0x01, 0xFF, 0x23, 0x23 };
//BYTE temp2_data[11] = { 0x40, 0x40, 0x00, 0x00, 0x03, 0xD3, 0x01, 0x01, 0xFF, 0x23, 0x23 };
//BYTE bo1_data[11] = { 0x40, 0x40, 0x00, 0x00, 0x03, 0xD4, 0x01, 0x01, 0xFF, 0x23, 0x23 };
//BYTE bo2_data[11] = { 0x40, 0x40, 0x00, 0x00, 0x03, 0xD5, 0x01, 0x01, 0xFF, 0x23, 0x23 };
示例代码如下:
//数据解析
#define MAX_FRAME_LENGTH 18 //最大帧长
DWORD ResolveData(BYTE* readBuf, DWORD dwLength)
{
int i, j, head_count, rest_length;
BYTE checkSum;
i = head_count = 0;
while (i < dwLength)
{
if (head_count == 2)//遇到了帧头
{
rest_length = dwLength - i;//这是正确的
if (rest_length >= MAX_FRAME_LENGTH)//最大帧长,这里是示例帧中的最大帧长,18
{
switch (readBuf[i + 3])
{
case 0xD1://PPG和ECG数据
checkSum = 0;
for (j = i + 3; j < i + 13; j++)
checkSum += readBuf[j];
if (checkSum == readBuf[i + 13])
{
//解析成功,消费数据...
i += 16;
head_count = 0;
}
else
{
head_count = 1;
i++;
}
break;
case 0xD2://温度1
checkSum = 0;
for (j = i + 3; j < i + 6; j++)
checkSum += readBuf[j];
if (checkSum == readBuf[i + 6])
{
//解析成功,消费数据...
i += 9;
head_count = 0;
}
else
{
head_count = 1;
i++;
}
break;
case 0xD3://温度2
checkSum = 0;
for (j = i + 3; j < i + 6; j++)
checkSum += readBuf[j];
if (checkSum == readBuf[i + 6])
{
//解析成功,消费数据...
i += 9;
head_count = 0;
}
else
{
head_count = 1;
i++;
}
break;
case 0xD4://血氧1
checkSum = 0;
for (j = i + 3; j < i + 6; j++)
checkSum += readBuf[j];
if (checkSum == readBuf[i + 6])
{
//解析成功,消费数据...
i += 9;
head_count = 0;
}
else
{
head_count = 1;
i++;
}
break;
case 0xD5://血氧2
checkSum = 0;
for (j = i + 3; j < i + 6; j++)
checkSum += readBuf[j];
if (checkSum == readBuf[i + 6])
{
//解析成功,消费数据...
i += 9;
head_count = 0;
}
else
{
head_count = 1;
i++;
}
break;
default:
head_count = 1;
i++;
break;
}
}
else
{
//将数据移至数组的开头,并改变下次将要读取的数据量
memcpy(readBuf, readBuf + i, rest_length);
return rest_length;
}
}
else
{
readBuf[i++] == 0x40 ? head_count++ : head_count = 0;
}
}
return 0;
}