場景:從服務端過來的數據很多,產生了粘包現象;現在根據對應的協議來進行拆包
思路:
Step1:找到幀頭,幀尾的位置
Step2:從buffer中取出幀數據,放到消息隊列中
Step3:循環從buffer裏面取數據,注意起始位置的變化 goto Step1
循環結束的條件:buffer裏面的長度 和 最後找到幀尾的數據相同
簡單的代碼實現:(這段只是針對那種多幀粘包的情況,對於缺包,其餘的情況還沒處理)
這裏處理的就是 幀頭:0x0A,0x7F 幀尾:0x0D 0x0A
示例代碼:(這裏代碼片段)
while (1)
{
for (i = datalen; i < len; i++)
{
if (0xAA == buffer[i] && 0x7F == buffer[i + 1])
{
iStart = i;
}
if (0x0D == buffer[i] && 0x0A == buffer[i + 1])
{
iEnd = i+1;
break;
}
}
for (j = iStart; j <= iEnd; j++)
{
message.Recvbuffer[j - iStart] = buffer[j];
}
//將分包的數據push到消息隊列中
message.msgType = SOCKMSG;
if (-1 == (msgsnd(pData->qid, &message, iEnd-iStart+1, 0)))
{
perror("msg closed! quit the system!\n");
bflag = true;
break;
}
memset(message.Recvbuffer, 0, MAX_BUF_SIZE);
datalen = iEnd;
if ((iEnd + 1) == len)
{
iStart = 0;
iEnd = 0;
datalen = 0;
printf("Process Success!\n");
break;
}
printf("iEnd:%d\n", iEnd);
iStart = 0;
iEnd = 0;
}
簡單來解釋下這段代碼:
buffer表示從server收過來的包,裏面可能包含若干個包;
輸出的結果示例:
AA 7F 00 00 04 72 65 65 19 51 5D 5D 61 40 54 5C 67 53 5F 6B 53 70 65 65 54 61 6C 6B 53 70 3C 9F 0D 0A
AA 7F 00 00 04 71 65 65 19 51 5D 5D 61 40 54 5C 67 53 5F 6B 53 70 65 65 54 61 6C 6B 53 70 C3 D4 0D 0A
AA 7F 00 00 04 73 65 65 19 51 5D 5D 61 40 54 5C 67 53 5F 6B 53 70 65 65 54 61 6C 6B 53 70 68 66 0D 0A
AA 7F 00 00 04 74 65 65 19 51 5D 5D 61 40 54 5C 67 53 5F 6B 53 70 65 65 54 61 6C 6B 53 70 C2 08 0D 0A
AA 7F 20 00 60 5A 65 65 19 51 5D 5D 61 40 54 5C 67 53 5F 52 62 49 51 53 64 50 5C 5B 61 40 5C 56 66 52 6C 6B 53 70 65 65 54 61 6C 6B 53 70 65 65 54 61 6C 6B 53 70 65 65 54 61 6C 6B 53 70 27 FE 0D 0A
類似這種結果