OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 8407|回复: 19

通信协议中的转义符怎么代码实现?

[复制链接]

30

主题

184

帖子

0

精华

高级会员

Rank: 4

积分
608
金钱
608
注册时间
2020-4-17
在线时间
111 小时
发表于 2021-6-9 14:34:56 | 显示全部楼层 |阅读模式
3金钱
这张图片中再增加了一个字符即0x1B。这个字符被定义为转义字符(也能够设置为别的),增加这个字符后的传输过程变为,0x02+用户数据+0x03。可是在用户数据中假设出现0x02即被替换为0x1B+0xE7,假设出现0x03即被替换为0x1B+0xE8。这样用户数据中就绝不会再出现0x02和0x03。可是万一用户要传输的数据就是0x1B+0xE7呢?这也没有关系,由于假设用户要传输的0x1B也会被转义为0x1B+0x00,所以假设用户真的须要传输0x1B+0xE7的话也被0x1B+0x00+0xE7所替代,也不会造成干扰。
这样做的结果是在接收端假设接收到转义字符,就必须要推断下一个字符是否为特定的三个值,假设是特定的三个值就须要做特殊处理,这就是转义字符解决通信中防止通信错误的原理。 企业微信截图_16232203788073.png

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

70

主题

6761

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
13097
金钱
13097
注册时间
2012-11-26
在线时间
3811 小时
发表于 2021-6-9 14:40:51 | 显示全部楼层
古老的协议,现在要是谁还弄转义符,简直是吃饱撑的
回复

使用道具 举报

12

主题

3389

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
8643
金钱
8643
注册时间
2020-5-11
在线时间
4096 小时
发表于 2021-6-9 14:54:46 | 显示全部楼层
本帖最后由 LcwSwust 于 2021-6-9 15:45 编辑

状态机,
收到02进入 接收数据状态,
接收数据状态收到1B进入转义状态,收到03则一帧结束,其它数据则存入数组。
转义状态收到数据进行转换后存入数组然后进入接收数据状态。
专治疑难杂症
回复

使用道具 举报

11

主题

2147

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4891
金钱
4891
注册时间
2015-1-10
在线时间
612 小时
发表于 2021-6-9 14:56:36 | 显示全部楼层
jermy_z 发表于 2021-6-9 14:40
古老的协议,现在要是谁还弄转义符,简直是吃饱撑的

别这么说,我们跟机智云有个IoT的项目,昨天他们发过来的协议还有转义字符,我也是一脸懵
回复

使用道具 举报

70

主题

6761

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
13097
金钱
13097
注册时间
2012-11-26
在线时间
3811 小时
发表于 2021-6-9 15:04:29 | 显示全部楼层
阿侑kevin 发表于 2021-6-9 14:56
别这么说,我们跟机智云有个IoT的项目,昨天他们发过来的协议还有转义字符,我也是一脸懵

协议问题,肯定是个老年人制定的协议
学无止境
回复

使用道具 举报

10

主题

778

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
6741
金钱
6741
注册时间
2017-4-12
在线时间
1258 小时
发表于 2021-6-9 15:15:22 | 显示全部楼层
本帖最后由 245925587 于 2021-6-9 15:21 编辑

转义就是把一个字节,转成特定的两个字节,如你那个0x02,封包的时候,遇到数据是0x02的,变成0x1B,0xE7,其他的同理;
反转义,就是接收的时候,遇到两个字节为特定的值,就反义回来,这种转义还是有很多标准协议用到,如GB17691,jt808等,这是为了接收方好处理;代码思路按照3楼说的,状态机的思路
回复

使用道具 举报

30

主题

184

帖子

0

精华

高级会员

Rank: 4

积分
608
金钱
608
注册时间
2020-4-17
在线时间
111 小时
 楼主| 发表于 2021-6-9 15:47:03 | 显示全部楼层
245925587 发表于 2021-6-9 15:15
转义就是把一个字节,转成特定的两个字节,如你那个0x02,封包的时候,遇到数据是0x02的,变成0x1B,0xE7,其 ...

是不是发送方把0x02转为0x1B和0xE7发送。接收方收到0x1B和XE7转为0x02
回复

使用道具 举报

70

主题

6761

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
13097
金钱
13097
注册时间
2012-11-26
在线时间
3811 小时
发表于 2021-6-9 15:57:39 | 显示全部楼层
跟紧我 发表于 2021-6-9 15:47
是不是发送方把0x02转为0x1B和0xE7发送。接收方收到0x1B和XE7转为0x02

是的,就是发送的时候遇到特定字符,膨胀为两个。
接收的时候,遇到两个连续的特定字节,转化为一个特定字符
学无止境
回复

使用道具 举报

30

主题

184

帖子

0

精华

高级会员

Rank: 4

积分
608
金钱
608
注册时间
2020-4-17
在线时间
111 小时
 楼主| 发表于 2021-6-9 16:59:56 | 显示全部楼层
jermy_z 发表于 2021-6-9 15:57
是的,就是发送的时候遇到特定字符,膨胀为两个。
接收的时候,遇到两个连续的特定字节,转化为一个特定 ...

感觉这样做很麻烦了。比如我要发送0x1B 0x1B 0x00就会转为0x1B 0x00 0x1B 0x00 0x00,平白多了两个字节,数据多的时候更是多出一大截。接收判断也很麻烦吧
回复

使用道具 举报

70

主题

6761

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
13097
金钱
13097
注册时间
2012-11-26
在线时间
3811 小时
发表于 2021-6-9 17:04:25 | 显示全部楼层
跟紧我 发表于 2021-6-9 16:59
感觉这样做很麻烦了。比如我要发送0x1B 0x1B 0x00就会转为0x1B 0x00 0x1B 0x00 0x00,平白多了两个字节, ...

那没办法,转移字符就是这么扯淡,所以说是古老的协议
学无止境
回复

使用道具 举报

30

主题

184

帖子

0

精华

高级会员

Rank: 4

积分
608
金钱
608
注册时间
2020-4-17
在线时间
111 小时
 楼主| 发表于 2021-6-9 17:27:14 | 显示全部楼层
jermy_z 发表于 2021-6-9 17:04
那没办法,转移字符就是这么扯淡,所以说是古老的协议

那现在有什么好的方法吗
回复

使用道具 举报

11

主题

2147

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4891
金钱
4891
注册时间
2015-1-10
在线时间
612 小时
发表于 2021-6-10 09:08:17 | 显示全部楼层
jermy_z 发表于 2021-6-9 15:04
协议问题,肯定是个老年人制定的协议

他们为了在接收数据包的时候只通过包头包尾就去判断是否为一包,不清楚怎么想的,反正他们觉得很高级
回复

使用道具 举报

70

主题

6761

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
13097
金钱
13097
注册时间
2012-11-26
在线时间
3811 小时
发表于 2021-6-10 09:32:04 | 显示全部楼层
跟紧我 发表于 2021-6-9 17:27
那现在有什么好的方法吗

你协议都定了,还有啥办法?
学无止境
回复

使用道具 举报

0

主题

65

帖子

0

精华

高级会员

Rank: 4

积分
523
金钱
523
注册时间
2017-12-21
在线时间
76 小时
发表于 2021-6-10 09:32:18 | 显示全部楼层
带有转义字符的协议还是很多的,比如国标的交通信号机就是,只通过帧头帧尾就能判断一帧,其实没什么调试难度.
回复

使用道具 举报

30

主题

184

帖子

0

精华

高级会员

Rank: 4

积分
608
金钱
608
注册时间
2020-4-17
在线时间
111 小时
 楼主| 发表于 2021-6-10 14:05:17 | 显示全部楼层
jermy_z 发表于 2021-6-10 09:32
你协议都定了,还有啥办法?

不是说转译字符古老吗,那现在一般用什么方法?
回复

使用道具 举报

2

主题

685

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3448
金钱
3448
注册时间
2017-7-4
在线时间
869 小时
发表于 2021-6-10 14:13:43 | 显示全部楼层
这跟古老和非古老有什么关系?就一个for循环遍历每一个字节即可,很简单的逻辑。另外,这是一个非常优秀、高效的协议,一些控制协议常用的,纯二进制传输,比那些字符串、json高效得多!
回复

使用道具 举报

70

主题

6761

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
13097
金钱
13097
注册时间
2012-11-26
在线时间
3811 小时
发表于 2021-6-10 14:23:18 | 显示全部楼层
跟紧我 发表于 2021-6-10 14:05
不是说转译字符古老吗,那现在一般用什么方法?

你去问下面那个称赞这个协议的吧,反正我觉得这个协议跟屎一样
学无止境
回复

使用道具 举报

2

主题

685

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3448
金钱
3448
注册时间
2017-7-4
在线时间
869 小时
发表于 2021-6-10 14:46:10 | 显示全部楼层
本帖最后由 Acuity 于 2021-6-10 14:51 编辑

伪代码:
  1. uint16_t decode_fun(uint8_t *src_data, uint16_t src_size, uint8_t *out_data)
  2. {
  3.     uint8_t index = 0;
  4.     uint16_t out_index = 0;

  5.     for (index=0; index<src_size; index++)
  6.     {
  7.         if (ESC == src_data[index])
  8.         {
  9.             index++;

  10.             if (0xE7 == src_data[index])
  11.             {
  12.                 out_data[out_index++] = STX;
  13.             }
  14.             else if (0xE8 == src_data[index])
  15.             {
  16.                 out_data[out_index++] = ETX;
  17.             }
  18.             else if (0x00 == src_data[index])
  19.             {
  20.                 out_data[out_index++] = ESC;
  21.             }
  22.             else
  23.             {
  24.                 /* todo error? */
  25.                 return 0;
  26.             }
  27.         }
  28.         else
  29.         {
  30.             out_data[out_data++] = src_data[index];
  31.         }
  32.     }
  33.    
  34.     return out_index;
  35. }
复制代码




回复

使用道具 举报

30

主题

184

帖子

0

精华

高级会员

Rank: 4

积分
608
金钱
608
注册时间
2020-4-17
在线时间
111 小时
 楼主| 发表于 2021-6-10 17:41:47 | 显示全部楼层
jermy_z 发表于 2021-6-10 14:23
你去问下面那个称赞这个协议的吧,反正我觉得这个协议跟屎一样

目前来看,没有更好的方法了。
回复

使用道具 举报

30

主题

184

帖子

0

精华

高级会员

Rank: 4

积分
608
金钱
608
注册时间
2020-4-17
在线时间
111 小时
 楼主| 发表于 2021-6-11 09:33:16 | 显示全部楼层

感谢分享
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-22 16:43

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表