首页UC › 基于socket简单通信协议实现(c/c++)

基于socket简单通信协议实现(c/c++)

1 场景
当用socket进行进程通信,传输数据的时候,会出现以下一些情况:

(1)完整的一条消息被系统拆分成几条发送,例如要发送一条消息:Hello World ,却被系统分成两条消息发送,分别为:Hello 和 World。

(2)几条独立的消息被系统合成一条消息发送,例如要发送两条消息分别为:a memory from my past和it’s been a year,却被系统和成一条消息发送:a memory from my pastit’s been a year。

这个时候,需要为socket通信设计一种通信协议,以保证数据的准确性。

2 协议格式
通信协议设计如下:
1339822494_2865
Head:帧头,2个字节,此处为0xa5a5
Type:通信类型,1个字节,范围0x00~0xff
Data Length:数据长度,1个字节,即Data的字节总数,
Data:实际传输的数据,长度不定
CS:校验值,1个字节,type、data length、data三个域所有字节的异或值,实际中并没用到校验
End:帧尾,2个字节,此处为0xbeef

3 程序设计

3.1    解析思路
假设socket客户端C和服务端S通信,C向S发送消息M1。

1、  S收到消息M1。S把消息M1拷贝到缓存Q中,Q为循环队列。假如M1的长度大于Q的剩余空间,则只拷贝剩余空间大小的字节到Q。

2、  从Q的当前指针开始,查找帧头<Head>。如果找到,则当前指针向后移2个字节位置,继续查找<Type>;如果没找到,则删除前1个字节,当前指针向后移1个字节位置,继续查找<Head>

3、  从Q的当前指针开始,查找<Type>。如果Q中至少还剩一个字节,则表示找到,当前指针向后移1个字节位置,否则退出解析。

4、  从Q的当前指针开始,查找<DataLength>。如果Q中至少还剩一个字节,则表示找到,当前指针向后移1个字节位置,否则退出解析。

5、  从Q的当前指针开始,向后移DataLength个字节位置,查找<End>。如果找到,则从Q中取出一条完整的消息P1,并从Q中删除此消息空间,调用外部的回调函数;否则删除帧头的第一个字节a5,当前指针指向帧头第二个字节a5位置,从步骤2开始,重新一轮解析。

3.2    数据结构

查找策略枚举,用于查找时判断查找帧结构的哪个部位:

消息结构体,用于存储从缓存中解析出的数据:

回调函数,用于从缓存中解析出消息时调用:

循环队列,用于缓存接收到的数据:

3.3 关键实现
1、把接收到的数据存储到缓冲中,并准备解析:

2、递归解析消息:

代码下载:socket_parse.zip

发表评论