資料解析
阿新 • • 發佈:2019-01-11
對於面向位元組流的協議,如串列埠通訊、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; }