场景:从服务端过来的数据很多,产生了粘包现象;现在根据对应的协议来进行拆包
思路:
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
类似这种结果