我制定的网络协议
[packlen,packcount,nowpack,data,datalen]
packlen | 占4字节 | 这个包的总字节数。 |
packcount | 占4字节 | 某些业务可能要发送很长的数据,但是一次性发送太多的数据会不稳定,所以业务层要讲数据切片分开,packcount就是指,此次数据交互总共发送了多少数据包。 |
nowpack | 占4字节 | 与packcount配合使用,代表当前包是第几个包。 |
data | 占packlen-4 -4个字节 | 这个包数据实体。 |
packlen | 占4个字节 | 最后在写入这个包的总字节数,用了与头部的packlen相呼应。 |
实例
//创建数据包;
char* CreatePack(int packCount, int nowPack, char* data, int datalen, int* out_packlen)
{
//第1个4是packlen,第2个4是packCount, 第3个4是nowPack,最后一个5是packlen;
int packlen = 4 + 4 + 4 + datalen + 4;
char* buffer = (char*)malloc(packlen);
memcpy(buffer, (char*)&packlen, 4);
memcpy(buffer + 4, (char*)&packCount, 4);
memcpy(buffer + 8, (char*)&nowPack, 4);
memcpy(buffer + 12, data, datalen);
memcpy(buffer + 12 + datalen, (char*)&packlen, 4);
*out_packlen = packlen;
return buffer;
}
例如,要发送"hello",5个字节,那么这个包应该是这样的:
接收端
- 调用API只读取4个字节转换为一个int,命名为packlen;
- 第二次调用API读取packlen-4个字节,命名为packdata,也就是协议中packlen后面的数据;
- 我们知道协议中最后的4个字节也是packlen,那么,(int)(packdata + (packlen-4-4))就应该等于packlen的值,可以用来判断这个包的正确性;
- *packdata 就是packcount;
- *(packdata+4)就是packnow;
- (packdata+8)就是data,那么data到哪结束呢?到packlen-4-4这个位置结束。
- 把(packdata+8)到(packdata+(packlen-4-4))这段数据发送给业务层进行处理。
- 循环往复。
如此一来,粘包的问题就解决了。