图解

image.png

文解

Coap协议的学习

1.什么是coap?

互联网的 WEB 已经无处不在,这些 WEB 服务又依赖于 WEB 的 REST 架构。

为了在大多的受限制节点上(例如 RAM 和 ROM 很有限的8位单片机)以及受限制网络上(例如 6LoWPAN)也能实现 REST 架构,人们着手处理“受限制的RESTful环境”,即CoRE。如6LoWPAN的受限网络支持将IPv6数据分成小包,但是这也极大降低的传输效率。CoAP的一个设计目标是保持很小的消息开销,因此限制了分包传输的需求。

CoAP 的主要目标之一是设计一个通用的 Web 协议,以满足这种受限环境的特殊要求,特别是考虑到能源,楼宇自动化和其他 M2M 应用。 CoAP 的目标不是盲目地压缩 HTTP [RFC2616],而是实现REST的一个通用 HTTP 子集,但针对 M2M 应用进行了优化。 虽然 CoAP 可用于将简单的 HTTP 接口转换为更紧凑的协议,但更重要的是,它还提供了 M2M 的功能,如内置发现,多播支持和异步消息传输。

本文档定义了 CoAP 协议,它可以很容易转换为 HTTP,以便集成到现有Web,同时它还能满足很多特殊要求,诸如组播支持,非常低的开销以及针对受限环境和M2M应用程序做了简化等。

总的来说,CoAP协议是为物联网中资源受限的设备制定的应用层协议。

2.Coap的消息传输

CoAP是一个完整的二进制应用层协议,运行在UDP上。

CoAP说明 - 图2
【Ver】版本编号,类似于IPv4和IPv6,仅仅是一个版本号。 2bit, 代表版本信息,当前是1

【T】报文类型,CoAP协议定了4种不同形式的报文,CON报文,NON报文,ACK报文和RST报文。 2bit
CON(0)——需要被确认的请求,如果CON请求被发送,那么对方必须做出响应。
NON(1)——不需要被确认的请求,如果NON请求被发送,那么对方不必做出回应。
我们在创建message对象的时候一般需要确定是CON或者NON以便服务端对消息作出正确的处理。
ACK(2)——应答消息,接受到CON消息的响应。
RST(3)——复位消息,当接收者接受到的消息包含一个错误,接受者解析消息或者不再关心发送者发送的内容,那么复位消息将会被发送

【TKL】CoAP标识符长度。CoAP协议中具有两种功能相似的标识符,一种为Message ID(报文编号),一种为Token(标识符)。其中每个报文均包含消息编号,但是标识符对于报文来说是非必须的。 4bit,token长度, 当前支持0~8B长度,其他长度保留将来扩展用

【Code】功能码/响应码。Code在CoAP请求报文和响应报文中具有不同的表现形式,Code占一个字节,它被分成了两部分,前3位一部分,后5位一部分,为了方便描述它被写成了c.dd结构。其中0.XX表示CoAP请求的某种方法,而2.XX、4.XX或5.XX则表示CoAP响应的某种具体表现。

  1. #### 请求方法 (存在于Code里面)
  2. 0.01 GET:获取资源
  3. 0.02 POST:创建资源
  4. 0.03 PUT:更新资源
  5. 0.04 DELETE:删除资源
  6. #### 返回数据的code (存在于Code里面)
  7. 1 Success 2.xx
  8. 这一类型的状态码,代表请求已成功被服务器接收、理解、并接受。
  9. 2.01 Created
  10. 2.02 Deleted
  11. 2.03 Valid
  12. 2.04 Changed
  13. 2.05 Content
  14. 2 Client Error 4.xx
  15. 这类的状态码代表了客户端看起来可能发生了错误,妨碍了服务器的处理。
  16. 4.00 Bad Request
  17. 4.01 Unauthorized
  18. 4.02 Bad Option
  19. 4.03 Forbidden
  20. 4.04 Not Found
  21. 4.05 Method Not Allowed
  22. 4.06 Not Acceptable
  23. 4.12 Precondition Failed
  24. 4.13 Request Entity Too Large
  25. 4.15 Unsupported Content-Format
  26. 3 Server Error 5.xx
  27. 这类状态码代表了服务器在处理请求的过程中有错误或者异常状态发生,也有可能是服务器的软硬件资源无法完成对请求的处理。
  28. 5.00 Internal Server Error
  29. 5.01 Not Implemented
  30. 5.02 Bad Gateway
  31. 5.03 Service Unavailable

【Message ID】报文编号。 16bit, 代表消息MID,每个消息都有一个ID ,重发的消息MID不变

【Token】标识符具体内容,通过TKL指定Token长度。
Message ID和Token都是跟随消息创建的时候的生成的随机标识

【Option】报文选项,通过报文选项可设定CoAP主机,CoAP URI,CoAP请求参数和负载媒体类型等等。
CoAP说明 - 图3
当一个消息报文里面有多个option时,每个option需要按照该option在协议里面对应的编号顺序排列下来。并且每个option索引是通过增量来计算的。option Delta 代表相对于前面一个option编号的增量。

  1. 第一个option的值为option的编号(编号图请参照下表)

CoAP说明 - 图4

  1. 如果一个message只有一个option 那么option delta = option的编号
  2. 如果同时存在多个option
  3. uint delta = option的编号 - 上次的option delta;//⚠️ unit表示大于0的数
  4. delta >= 269 option delta = 14 extendedDelta = delta - 269
  5. delta >= 13 option delta = 13 extendedDelta = delta - 13
  6. 其他的时候option delta就等于 delta
  7. option length这个计算就不用说了
  8. 最后一部分的value先来看一下代码的计算
  9. NSString *valueForKey;
  10. if ([key intValue] == IC_ETAG || [key intValue] == IC_IF_MATCH) {
  11. //当编号为ETAG和IF_MATCH的时候
  12. valueForKey = [valueArray objectAtIndex:i];
  13. }
  14. else if ([key intValue] == IC_BLOCK2 || [key intValue] == IC_URI_PORT || [key intValue] == IC_CONTENT_FORMAT || [key intValue] == IC_MAX_AGE || [key intValue] == IC_ACCEPT || [key intValue] == IC_SIZE1 || [key intValue] == IC_SIZE2) {
  15. //这些key的时候把传过来的value需要进行转换成16进制的
  16. valueForKey = [NSString get0To4ByteHexStringFromInt:[[valueArray objectAtIndex:i] intValue]];
  17. }
  18. else {
  19. //其他的直接把传过来的value放进去就可以
  20. valueForKey = [NSString hexStringFromString:[valueArray objectAtIndex:i]];
  21. }
  22. coap的观察者模式
  23. 持续监听设备的状态
  24. +-----+---+---+---+---+---------+------------+-----------+---------+
  25. | No. | C | U | N | R | Name | Format | Length | Default |
  26. +-----+---+---+---+---+---------+------------+-----------+---------+
  27. | 6 | | x | - | | Observe | uint | 0-3 B | (none) |
  28. +-----+---+---+---+---+---------+------------+-----------+---------+
  29. oberser value 0 代表向服务器端订阅一个主题。
  30. oberser value 1 代表向服务器端移除一个已订阅主题。

块传输 Block

需要传输大量数据时,比如一个大文件,需要采用分块传输,把文件拆解成多个块进行传输。扩展的块传输协议在COAP基础协议上增加了3个options, 2个response codes 用于块传输大小协商及控制。
CoAP说明 - 图5
上面这张图代表的是传输区块的编号和名称
CoAP说明 - 图6
上面的这个代表服务端的接收情况

block的传输格式

CoAP说明 - 图7

  1. M: More Flag,占用1bit 代表是否还有剩下数据块未传输。如果设置为0,代表数据块都已传输出去
  2. NUM: Block Number 占用0~3Byte,代表当前块编号,以0开始, 如我们要传10个数据块,则数据块的编号为0~9
  3. SZX: Block Size,占用2bit,取值范围0~6,对应每个block 大小为2xxSZX+4),即范围(16 ~ 1024),以Byte为单位
  4. option block1 主要用于客户端发出请求时,分块传输,比如需要上传一个大的数据包到服务器上。
  5. option block2 主要用于服务器端响应时,分块传输, 比如设备端发起资源发现式,由于服务器上资源较多,就要启动分块传输。
  6. Size option
  7. 主要用于向对方说明,这次块传输需要传送的数据总数量。
  8. Size1 option 代表客户度发出请求里面资源总的大小。
  9. Size2 option 代表服务器端响应资源总的大小。
  10. ###如何启动块传输?
  11. 当请求消息或者响应消息里面有出息 block1/block2 option时,代表这是块传输通信。需要根据option block 里面M标识,决定是否继续进行块传输。

CoAP说明 - 图8

  1. 第一个消息,客户端发起发现资源请求信息CON并设置Block20(NUM)/0(M)/64SZX)告诉服务器端,能接受最大block size64.
  2. 第二个消息。服务器端回复确认消息ACK,并设置Block20/1/64,告诉客户端,block size已接受为64 且后面还有数据,当前传输块编号是0. size21094 告诉客户端,接下来总的数据大小是1094B
  3. 第三个消息,客户端发起请求获取下一个block。设置Block21/0/64.告诉服务器端下一个要获取的block编号是1.

一个CoAP Client可以分次向CoAP server订阅多个资源主题。 一个CoAP server上的主题可以被多个观察者(CoAP Client)订阅。 这样就通过了CoAP server实现了CoAP Client之间直接数据转发通信。这些都可以通过option实现

【Payload】真正有用的被交互的数据。 是可选的,如果有的话,前面加上0XFF

安全(DTLS)

COAP使用DTLS来做安全传输层,该层运行于UDP之上.
CoAP说明 - 图9

DTLS里面是含有UDP的,coap的DTLS是需要在DTLS的UDP里面实现coap协议

7.参考协议

COAP基本协议 RFC7252

块传输协议 RFC7959

订阅与发布 RFC7641

8.HTTP,coap,MQTT的对比

  1. HTTPCoAPMQTT
  2. CoAP协议的设计参考了HTTPCoAPMQTT都是行之有效的物联网协议,一下为它们之间的异同。
  3. HTTPCoAP
  4. HTTP代表超文本传输协议,CoAP代表约束应用协议;
  5. HTTP协议的传输层采用了TCPCoAP协议的传输层使用UDP
  6. CoAP协议是HTTP协议的简化版;
  7. CoAP协议和HTTP协议一样使用请求/响应模型,拥有相同的方法;
  8. CoAP开销更低,并支持多播;
  9. CoAP专为资源构成应用而设计,如:IoT/WSN/M2M等...
  10. CoAPMQTT
  11. MQTT协议使用发布/订阅模型,CoAP协议使用请求/响应模型;
  12. MQTT是长连接,CoAP协议是无连接;
  13. MQTT通过中间代理传递消息的多对多协议,CoAP协议是ServerClient之间消息传递的单对单协议;
  14. MQTT不支持带有类型或者其它帮助Clients理解的标签消息,CoAP内置内容协商和发现支持,允许设备彼此窥测以找到交换数据的方式。