CoAP是一种应用层协议,运行于UDP协议之上,非常小巧,最小的数据包仅4字节。

CoAP协议定义

CoAP协议的交互模型与HTTP的客户端/服务端模型类似。然而,在M2M的交互场景中,CoAP的目标是设计一个通用的网络协议,满足受限环境的特殊需求,特别考虑了能源、楼宇自动化和其他M2M应用。

需要注意的是CoAP并不能代替HTTP协议,但是对于那些小设备(例如CPU为8bit的单片机,内存32Kb,Flash 256Kb)而言CoAP的确是一个更好的解决方案。

CoAP协议特点

满足受限环境下M2M的需求的协议

CoAP协议基于UDP

异步消息交换

轻量级的头部,且解析复杂度低。

支持URI和Content-Type

能实现简单的缓存和数据代理

无状态的HTTP映射,可以构建代理服务器,使CoAP资源可以用HTTP协议访问,也可以使HTTP接口实现于CoAP协议之上

支持DTLS

协议模型

coap协议Java包 coap协议分层模型_客户端

逻辑上分为Messages和Requset/Respones两层,R/R通过Messages承载,从封包上不体现这种层次结构

DTLS可选,由于基于UDP,支持组播。

特征

基于UDP的类似HTTP的Client/Server交互模型

Client发送Request(携带不同method)请求对资源(通过URI表示)的操作,Server返回Response(携带资源的representation)和状态码

在M2M应用场景,Endpoint实际同时是Server和Client

协议定义了以下几个角色:

Endpoint:CoAP协议的参与方

Sender(发送方):发出Messages的Endpoint

Recipient(接收方):相当于接收Message的Endpoint

Client(客户端):发出Request的Endpoint,Response的destination Endpoint

Server(服务端):Request的destination,Response的source Endpoint

Origin Server(源服务端):resource所在的ServerElective(存储或者创建一个给定资源的服务端)

Intermediary(媒介):既作为Server又作为Origin Server的Client的Endpoint。可以理解为Proxy的统称

Proxy:一种Intermediary,完成Request前转,Respone中继,执行缓存,namespace转换,协议转换等功能的Endpoint,基于前转请求架构中的位置,协议定义了forward-proxy和reverse-proxy两种代理

Forward-Proxy(正向代理):被Client用于代表Client执行Request,并完成任何必要的转换。

Reverse-Proxy(反向代理):代表一个或多个其他服务器并代表它们满足请求,执行任何必要的翻译的端点。 与转发代理不同,客户端可能不知道它正在与反向代理通信; 反向代理接收请求,就像它是目标资源的源服务器一样。

CoAP-to-CoAP Proxy:映射CoAP request到CoAP request

Cross-Proxy:跨协议代理,比如CoAP-to-HTTP或HTTP-to-CoAP

Message Format

Message组成部分

固定的4个字节的头部

0-8字节的Token

0或者多个TLV(Type-Length-Value)格式的Option (在下面会有详解图↓)

可选的Payload

Message的承载信息

Request

Response

Empty Message(只有message header,且code为0.00)注:最短的消息报文就是只有头文件和返回信息,无承载信息。

Message Hader(CoAP报文结构)

coap协议Java包 coap协议分层模型_coap协议Java包_02

Ver:版本编号,指示CoAP协议的版本号。类似于HTTP 1.0 HTTP 1.1,2位。

TKL:Token Length,Token长度,当前有效取值0-8,其他认为是Message format error,4位。

T:报文类型,CoAP协议定了4种不同形式的报文,CON报文,NON报文,ACK报文和RST报文,2位。

Code:功能码/响应码,格式 c(3bit class type).dd(5bit detail code)Code在CoAP请求报文和响应报文中具有不同的表现形式,Code占一个字节,它被分成了两部分,前3位一部分,后5位一部分,为了   方便阅读,Code被描述为c.dd结构,其中0.XX表示CoAP请求的某种方法,而2.XX、4.XX或5.XX则表示CoAP响应的某种具体表现。8位无符号数。

CoAP定义的Request方法有如下4种:

0.01:GET方法——用于获取某资源

0.02:POST方法——用于创建某资源

0.03:PUT方法——用于更新某资源

0.04:DELECT——用于删除某资源

特例:0.00表示empty message  (注:既不是request也不是response的message。empty message并不是协议定义和上述Message并列的Type,只是一种特殊含义的Message。)

对于不能识别的方法,需要返回一个4.05(method not allowed 类型不允许)的Piggybacked response。

Message ID:报文编号,用于重复消息检测、匹配消息类型等以及Confirmable msg,non-Confirmable msg和ACK、reset msg的匹配,每个CoAP报文都有一个ID,在一次会话中ID总是保持不变。但是在这个会话结束之后,该ID会被回收利用。(需要注意的是每个报文都包含报文编号但不一定包含Token)

Token:标识符具体内容,通过TKL指定Token长度,用于匹配Request和Response。(用来标记请求和回复的,比如暂时无法应答,一会服务器应答客户端如何确认应答的是哪个消息呢?使用Token)

Option:报文选项,通过报文选项可设定CoAP主机,CoAP URI,CoAP请求参数和负载媒体类型等等。

1111 1111:分隔符,CoAP报文和具体负载之间的分隔符,固定一个字节。

Payload:交互的数据,真正有用的被交互的数据。

除了Ver、T、TKE、Code、Message ID之外其他的都是可选的,这也是为什么最小的数据包仅4个字节的原因。

CoAP的响应码

coap协议Java包 coap协议分层模型_客户端_03

 

ETag:是实体标签(Entity Tag)的缩写。ETag一般不以明文形式响应给客户端。在资源的各个生命周期中,它都具有不同的值,用于标识出资源的状态。当资源发生变更时,如果其头信息中一个或者多个发生变化,或者消息实体发生变化那么ETag也随之发生变化。

ETag值的变更说明资源状态已经被修改。往往可以通过时间戳就可以得到ETag头信息。服务器计算ETag值,并在相应客户端请求时将它返回给客户端。

coap协议Java包 coap协议分层模型_Server_04

 

此类Code(4.XX)用于表示可能的客户端错误,可以应用于所有method的response,并应该包含一个Diagnostic payload;此类Code的Response是cacheable的。

coap协议Java包 coap协议分层模型_Server_05

Message分类

解析CoAP报文结构提到过,CoAP协议定了4种不同形式的报文,CON报文,NON报文,ACK报文和RST报文。

coap协议Java包 coap协议分层模型_coap协议Java包_06

1. 需要确认消息 CON

2. 不需要确认消息 NON (适用于消息会重复频繁的发送,丢掉消息不对业务产生影响)

3. 确认应答消息 ACK

4. 复位消息(相当于一种拒绝信息) RST

Message的可靠传输

coap协议Java包 coap协议分层模型_coap协议Java包_07

 

Client构造Con Msg 发送到Server,未收到ACK或Reset时,支持基于指数回退的重发;

注释:客户端发送消息到服务端,需要等待服务器收到通知, 如果在规定时间内没有收到确认消息(ACK)或者复位消息(RST),需要重新发送数据。

Server如果可以处理该Message,返回ACK,否则返回Reset

注释:可靠传输是基于CON消息传输的,服务器端收到CON类型的消息后,如果服务器可以处理这个消息,需要返回ACK消息,客户端到在指定时间ACK_TIMEOUT内收到ACK消息后,才代表这个消息已可靠到服务器端,不能处理的话就Rejecting一个消息,一般是返回Reset或者忽略它。

Message的可靠传输

coap协议Java包 coap协议分层模型_Server_08

coap协议Java包 coap协议分层模型_Server_09

coap协议Java包 coap协议分层模型_coap协议Java包_10

注释:**为幂运算符

Message的非可靠传输

coap协议Java包 coap协议分层模型_HTTP_11

Client对于不需要可靠传输的Message通过Non-Confirmable Msg传递

虽然不需要ACK确认NON Msg,Server仍然可能会返回Reset给Client(比如Server不能处理这个NON msg)

注释:不可靠传输是基于NON消息传输的。服务器端收到NON类型的消息后,不用回复ACK消息。

coap协议Java包 coap协议分层模型_客户端_12

 

 

Request/Respones模型

CoAP Request和Response的语法通过Message承载

可靠传输Request的响应方式有两种:

同步可靠响应模式: 通过Con msg的ACK携带Response

异步可靠响应模式:当Server不能立即响应Request时,可以先通过空Ack msg响应Client,当Server准备好后,通过新的CON Msg将resonse发送给Client

非可靠传输Request和Response

同步可靠响应模式(piggybacked Response)

coap协议Java包 coap协议分层模型_Server_13

异步可靠响应模式(separate Response)

coap协议Java包 coap协议分层模型_HTTP_14

非可靠响应模式

coap协议Java包 coap协议分层模型_coap协议Java包_15

COAP 请求响应Response代码: 响应内容也与HTTP协议类似, 主要有如下3类:

  • Success 2.xx 代表客户端请求被成功接收并被成功处理
  • Client Error 4.xx 代表客户端请求有错误,比如参数错误等
  • Server Error 5.xx 代表服务器在执行客户端请求时出错。

Option分类

协议定义了Option,Option的属性有如下几类:

Critical Option(重要选项):接收方必须能够理解的Option,否则消息无法正常处理。

Elective Option(非重要选项):接收方不识别该Option时,可以忽略,不影响消息的正常处理。

注意: Option本身和字面意义一样,是否出现在Message中是可选的(上面有提到)

Unsafe Option(不安全的选项):Proxy不识别 不能转发其所在Message的Option,并不是每个Critical Option都是Unsafe Option

Safe-to Forward Option(转发安全选项):Proxy不识别仍可转发其所在Message的Option

根据Endpoint对于不能识别的Option如何分类,有如下规则:

对于不能识别的非重要选项,无声的忽略该选项。

在Con Request中的不能识别的重要选项,需要返回4.02(请求中包含错误选项),且携带该选项用于诊断。

在Con Response中或者附带响应数据中不能识别的重要选项,必须拒绝接受这个Response。

在Non(不需应答消息)中不能识别的选项,必须拒绝接受这个消息(返回reset并忽略non)。

Rejecting a Confirmable message is effected by sending a matching,Reset message and otherwise ignoring it.(拒绝可确认消息是通过发送匹配来实现的,重置消息而忽略它。)

Option Format

coap协议Java包 coap协议分层模型_HTTP_16

        简单的来讲Option作为报文选项有许多的选项编号,每一个编号有不同的选项含义,例如(1——If-Match)(2——Uri-Host),CoAP协议里是用编号来表示选项的含义的,而且是一种增量的方式来表示的,Option的实际编号实际上是根据Option的Delta值和上一个Option相加得出来的,例如上一个Option是12,这个Option Delta是1,12+1=13。

RFC7252中是这样写的:

The fields in an option are defined as follows:

Option Delta: 4-bit unsigned integer. A value between 0 and 12 indicates the Option Delta. Three values are reserved for special constructs:

13: An 8-bit unsigned integer follows the initial byte and indicates the Option Delta minus 13.

14: A 16-bit unsigned integer in network byte order follows the initial byte and indicates the Option Delta minus 269.

15: Reserved for the Payload Marker. If the field is set to this value but the entire byte is not the payload marker, this MUST be processed as a message format error

The Option Number is calculated by simply summing the Option Delta values of this and all previous options before it.

CoAP中Option的定义

coap协议Java包 coap协议分层模型_HTTP_17

 

 

coap协议Java包 coap协议分层模型_Server_18

Option内容项

coap协议Java包 coap协议分层模型_coap协议Java包_19

CoAP的块传输、代理和安全

块传输

RFC7959定义了CoAP协议的块输出规范,对于resource representation无法通过一个CoAP数据包承载时,发起块传输过程

为何在CoAP引入块传输

CoAP基于UDP,最大传输数据报的长度为64KByte,无法支持FW升级(除非开发基于CoAP的特定应用)

避免数据报文分片(基于IP)

避免适配层分片(基于RFC4919 6LoWPAN)

 

代理

物联网不能以孤立网络的形式存在,必须通过一定的方式与其他外部网络互联,使其他外部网络能够访问和控制物联网,这样才有实际价值。物联网是基于CoAP通讯的,互联网是基于HTTP通讯的,那么怎样融合两者呢?这里需要有CoAP-HTTP或者HTTP-CoAP的代理。可以在网关上或者服务器端实现代理。

按代理方向分为以下两种工作模式:

CoAP-HTTP Proxying

CoAP Client通过该代理访问HTTP Server上resource的资源, Client通过发送携带Proxy-URI或者Proxy-Scheme指定到http或https URI的Request发起该访问过程

HTTP-CoAP Proxying

HTTP Client通过该代理访问CoAP Server. 上的资源,通过在HTTP Request的request-line中指定URI格式为coap或者coaps发起该访问过程。

对于Safe-to-Forward options必须forward。

Forward-Proxies

作用是代理发往Server的Request。在Request message中使用Proxy-Uri Option表明Proxy,使用Uri-Host, Uri-Port, Uri-Path, and Uri-Query Options表明origin server。

Reverse-Proxies

不使用Proxy-Uri Option。

coap协议Java包 coap协议分层模型_Server_20

安全

coap协议Java包 coap协议分层模型_Server_21

 

 

 

参考资料:

RFC 7252:  https://datatracker.ietf.org/doc/rfc7252/?include_text=1

CoAP协议详解完整版:https://wenku.baidu.com/view/d1fb86a0dcccda38376baf1ffc4ffe473268fdc8.html