最近的一个项目中用到了coap,为了防止时间过长导致遗忘,将具体的关键知识写在这里,同时也为后来人减少一些坑。

Coap

coap是一种符合REST规范(主要是幂等性)的,适用于物联网通讯的数据协议。具体使用起来和http比较类似,同样有着GET、POST、PUT、DELETE四种操作,不过coap是基于udp的,并且数据包是按字节码拼接的,甚至有些信息是按位标识的,不像是http一样用各种字符串来表达各个部分。

省流量、计算少、适合物联网,但是在当前ipv6没有普及之时,实时性不如mqtt。

coap数据包格式的资料

在查找相关资料时,发现官方的资料长达一百多页(https://tools.ietf.org/html/rfc7252),虽然很全面,但是我并不需要如此详细的文档,另外还不知道coap基本长啥样呢。

我就基于这个笔记,来简单解释一下整个coap数据包的格式,并在最后实际测试一下几个实例数据包。

数据包的整体结构

coap的数据包格式类似于下面这样:

coap版本(Ver)

coap版本信息占用为2位(1/4字节)

现在的coap版本来说,固定是01

消息类型(T)

消息类型占用的大小位2位(1/4字节),类型如下四种:具体数值消息类型名称0CONfirmable

1NON-confirmable

2ACKnowledgement

3ReSeT

CON类型的消息为主动发出消息请求,并且需要接收方作出回复

NON类型的消息为主动发出消息请求,但是不需要接收方作出回复

ACK类型的消息为接收方作出回复

Res类型为发出CON消息后,在还没收到请求时,主动通知不需要再回复

token长度(token length,TKL)

token长度占用4位(0.5字节),表示后面的token所占的字节数。

可以为0,表示token不存在。

coap状态码(Code)

状态码占用1个字节,分为两种:发送和接收

发送方的状态码状态码请求类型实际数值0.00EMPTY0x00

0.01GET0x01

0.02POST0x02

0.03PUT0x03

0.04DELETE0x04

一般empty只在消息类型为ReS的时候才会用到

响应方的状态码

类型:SuccessCodeDescription2.01 (65, 0x41)Created

2.02 (66, 0x42)Deleted

2.03 (67, 0x43)Valid

2.04 (68, 0x44)Changed

2.05 (69, 0x45)Content

2.31 (95, 0x5F)Continue

类型:Client ErrorCodeDescription4.00 (128, 0x80)Bad Request

4.01 (129, 0x81)Unauthorized

4.02 (130, 0x82)Bad Option

4.03 (131, 0x83)Forbidden

4.04 (132, 0x84)Not Found

4.05 (133, 0x85)Method Not Allowed

4.06 (134, 0x86)Not Acceptable

4.08 (136, 0x88)Request Entity Incomplete

4.12 (140, 0x8C)Precondition Failed

4.13 (141, 0x8D)Request Entity Too Large

4.15 (143, 0x8F)Unsupported Content-Format

类型:Server ErrorCodeDescription5.00 (160, 0xA0)Internal Server Error

5.01 (161, 0xA1)Not Implemented

5.02 (162, 0xA2)Bad Gateway

5.03 (163, 0xA3)Service Unavailable

5.04 (164, 0xA4)Gateway Timeout

5.05 (165, 0xA5)Proxying Not Supported

其中a.bb为响应代码,转成二进制的代码格式如下:

如2.31,拆开分成2进制为:

010 11111

转成16进制则为:0x5f

一般返回2.xx即为响应成功,其他一般都是失败,和http协议比较类似

消息编号(Message ID)

消息编号占用2字节,代表了该消息的编号,如果是CON类型的消息,在返回时消息编号也应当与发送时相同

Token

Token的字节数由之前的token长度(token length,TKL)决定,如果前面的TKL值是0,则数据包中不包含token

Options

Options占用的字节数不定,如果包尾遇到payload标识符0xff则表示Options数据结束

Options类似于http协议中的Options,有Content-Format、Uri-Path之类的信息,格式解析与组包较为复杂,具体结构与其代表的数值如下:No.NameFormatLengthDefault1If-Matchopaque0-8(none)

3Uri-Hoststring1-255(see note 1)

4ETagopaque1-8(none)

5If-None-Matchempty0(none)

7Uri-Portuint0-2(see note 1)

8Location-Pathstring0-255(none)

11Uri-Pathstring0-255(none)

12Content-Formatuint0-2(none)

14Max-Ageuint0-460

15Uri-Querystring0-255(none)

17Acceptuint0-2(none)

20Location-Querystring0-255(none)

28Size2uint0-4(none)

35Proxy-Uristring1-1034(none)

39Proxy-Schemestring1-255(none)

60Size1uint0-4(none)

Content-Formats参数的具体数值:Media typeId.text/plain;charset=utf-80

application/link-format40

application/xml41

application/octet-stream42

application/exi47

application/json50

application/cbor60

Option Delta

Option Delta占用4位(0.5字节)

Option Delta代表Option的类型,该值代表了上表中Option类型的代码值与上一个Option代码值之间的差值

(如果该Option为第一个Option,则直接表达该Option的Option Delta)

由于Option Delta只有4位,最大只能表达15,为了解决这个问题,coap协议有着如下规定:当Option Delta号码<=12时:Option Delta位为实际的Option Delta值

当Option Delta号码<269时:Option Delta位填入13;并且在后面的Option Delta(extended)位会占用1字节,并且填入的数为实际Option Delta值减去13

当Option Delta号码<65804时:Option Delta位填入14;并且在后面的Option Delta(extended)位会占用2字节,并且填入的数为实际Option Delta值减去269

特别注意,填入的Option Delta值不可能为15(0x0f)当遇到15时,该包无效

Option Length

Option Length占用4位(0.5字节)

Option Length代表该option所包含数据(value)的长度,该值的表示方法类似于Option Delta,如下:当Option Length号码<=12时:Option Length位为实际的Option Length值

当Option Length号码<269时:Option Length位填入13;并且在后面的Option Length(extended)位会占用1字节,并且填入的数为实际Option Length值减去13

当Option Length号码<65804时:Option Length位填入14;并且在后面的Option Length(extended)位会占用2字节,并且填入的数为实际Option Length值减去269

填入的Option Length值不可能为15,当遇到15时,该包无效

Option Delta(extended)和Option Length(extended)

Option Delta(extended)和Option Length(extended)的意义在上面已经解释过了,在不需要这两个值的情况下,这两个部分的数据便不存在

多个option的情况

当有多个option时,这些option必须是按option代码值(No.)的顺序**从小到大**排列的,不然会导致Option Delta的值出错

每个部分的option各自按格式组包,最后按顺序拼到一起,并入字节流中

负载内容(Payload)

Payload占用字节数不定

当Payload不存在时,数据包末尾不能加上0xff的分隔符

如果存在0xff的分隔符,则分隔符后的数据便是Payload

解释结束,举个实际例子

在网上有一个coap测试服务器,域名为coap.me

我们假设一个例子,用串口工具将这个例子发出

假设需要请求coap.me,5683端口的coap数据,GET请求,网址如下:coap://coap.me:5683/path/sub1

首先不管服务器,先分析一下数据包格式:版本号:01(二进制)

消息类型:00(二进制,表示CON)

token长度:0010(二进制,表示2字节)

请求码:0x01(GET)

消息id:0x1234(随便编的)

token:0x5678(随便编的)

到了Options这里,我们就要再小小分析一下了,这个请求有两个Options:

Uri-Path:path

Uri-Path:sub1

所以数据包格式接着上面:Option Delta:1011(二进制,表示编号11)

Option Length:0100(二进制,表示4字节)

Option Delta(extended):空

Option Length(extended):空

Option Value:0x70 61 74 68(字符串path)

Option Delta:0000(二进制,表示上一个编号11 + 0)

Option Length:0100(二进制,表示4字节)

Option Delta(extended):空

Option Length(extended):空

Option Value:0x73 75 62 31(字符串sub1)

该请求没有payload,所以也就不去构造payload了

数据完整的16进制代码为:42 01 12 34 56 78 B4 70 61 74 68 04 73 75 62 31

我们用工具测试一下:

收到的回复为:62 45 12 34 56 78 48 CB B0 EF 05 63 11 E3 84 80 FF 54 44 5F 43 4F 52 45 5F 43 4F 41 50 5F 30 39 20 73 75 62 31

解包分析一下:01:协议版本号

10:消息类型,ACK

0010:token长度2字节

0x45:响应代码2.05,Content

0x12 34:消息id

0x56 78:token内容

0x48:option类型ETag,8字节

0xCB B0 EF 05 63 11 E3 84:ETag内容

0x80:option类型Content-Format,0字节

0xFF:和payload消息的分隔符

0x54 44 5F 43 4F 52 45 5F 43 4F 41 50 5F 30 39 20 73 75 62 31:payload内容,解码结果为TD_CORE_COAP_09 sub1

分析完毕,下一篇文章就可以讲解用lua代码来进行组包与拆包了

coap 返回版本信息_coap组包格式的简单解析相关推荐

  1. coap 返回版本信息_CoAP 协议解析说明(转)

    CoAP 协议全面分析 HTTP与COAP 请求与响应示例 HTTP请求(文本格式) POST https://getman.cn/echo HTTP/1.1 User-Agent: Fiddler ...

  2. coap 返回版本信息_CoAP协议详解

    The Constrained Application Protocol(CoAP)是一种专用的Web传输协议,用于受约束的节点和受约束的(例如,低功率,有损)网络. 节点通常具有带少量ROM和RAM ...

  3. coap 返回版本信息_CoAP协议学习笔记

    CoAP是一种应用层协议,运行于UDP协议之上,非常小巧,最小的数据包仅4字节. CoAP协议定义 CoAP协议的交互模型与HTTP的客户端/服务端模型类似.然而,在M2M的交互场景中,CoAP的目标 ...

  4. python删除软件后cmd还是返回版本信息

    我想安装另外一个版本的pandoc,明明已经删除掉了,但是还是会返回版本信息,而且给的文件位置也不存在,再次启动删除又显示未安装. 解决办法:我的python是通过anaconda安装的,如果其他的方 ...

  5. 解析北斗部标协议_北斗数据包格式封装和解析

    /// ///北斗数据包 封装/// public class BeiDouContentEncoderHandler : MessageToByteEncoder{protected overrid ...

  6. Qt 实现数据协议控制--组帧、组包、解析帧、解析包

    数据传输中的组帧和组包 一.数据帧,数据包的概念 数据帧 组包 二. 程序实现: 2.1.frame(帧)类的实现: 2.2.Pack(包)类的实现: 三.测试 一.数据帧,数据包的概念 数据帧 数据 ...

  7. Bank相关11_8583报文手动组包——详细分析每个示范域

    8583报文作为一种应用较广的报文,有它独特的格式. 网上有关8583报文的说明很多.但涉及到每个域的详细例子就较少了.这里列出各个域的详细例子,供参考. 8583报文: 报文组成: 报文头[长度(2 ...

  8. 隐藏tomcat页面异常显示的版本信息

    1.正常情况下,tomcat遇到404或500会返回版本信息: 在这里插入图片描述 .在linux环境下 进入lib路径 unzip catalina.jar 编辑ServerInfo.propert ...

  9. android 获取apk的版本信息

    今天,简单讲讲android如何获取apk的版本信息. 这个很简单,但是之前还是查找了资料,所以记录一下. 一.应用程序得到自己的版本信息 /*** 得到当前应用版本名称的方法* * @param c ...

最新文章

  1. 微信小程序中的tabBar设置
  2. 完整年份值必须介于_上 | 完整解释 Monad 程序员范畴论入门
  3. TYVJ 1557 MST+LCA
  4. Sqlite 错误码
  5. router vue 多个路径_多个vue子路由文件自动化合并的方法,
  6. java如何解压rar文件怎么打开,java解压rar文件
  7. 用python重构策略模式
  8. Centos查看与关闭防火墙
  9. rtmp之谷歌浏览器默认启用flash
  10. java找不到路径应该怎么弄_cd java 找不到指定路径
  11. 浅谈人机工程应用在数字化工艺中的作用
  12. 关于Android及iOS打包
  13. 2年修完6个清华CS硕士学位第3周反思报告
  14. 国家图书馆最新推荐70本书
  15. OpenMP学习笔记之常用指令parallel/sections/critical 其余待续
  16. 学渣的刷题之旅 leetcode刷题 3. 无重复字符的最长子串(暴力法、滑动窗口)
  17. 计算机用户分配盘符,盘符划分不求人 Win7硬盘分区多面看
  18. CD网站用户消费数据分析案例
  19. Android二维码扫描开发(一):实现思路与原理
  20. 【批处理DOS-CMD命令-汇总和小结】-上网和网络通信相关命令(netsh)

热门文章

  1. 创业型公司,你要不要去?
  2. codeforces 1526C1 Potions (Easy Version)
  3. java实现手机尾号评分
  4. linux 命令修改uid,修改Linux用户的UID、GID
  5. 家到学校路线图怎么画_PPT绘制家到学校路线图教程
  6. 通过puppet hiera配置bigtop大数据集群
  7. nginx使用ngx_shared_memory_add和ngx_slab_alloc等在共享内存里创建一棵红黑树
  8. 【思维导图】canny滤波 原理步骤细致剖析
  9. Web 前端通过调用ActiveX实现LPT1端口小票机打印功能。
  10. 软件工程计算机水平 推荐表,软件工程就业推荐表2014届.doc