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
协议模型
逻辑上分为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报文结构)
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的响应码
ETag:是实体标签(Entity Tag)的缩写。ETag一般不以明文形式响应给客户端。在资源的各个生命周期中,它都具有不同的值,用于标识出资源的状态。当资源发生变更时,如果其头信息中一个或者多个发生变化,或者消息实体发生变化那么ETag也随之发生变化。
ETag值的变更说明资源状态已经被修改。往往可以通过时间戳就可以得到ETag头信息。服务器计算ETag值,并在相应客户端请求时将它返回给客户端。
此类Code(4.XX)用于表示可能的客户端错误,可以应用于所有method的response,并应该包含一个Diagnostic payload;此类Code的Response是cacheable的。
Message分类
解析CoAP报文结构提到过,CoAP协议定了4种不同形式的报文,CON报文,NON报文,ACK报文和RST报文。
1. 需要确认消息 CON
2. 不需要确认消息 NON (适用于消息会重复频繁的发送,丢掉消息不对业务产生影响)
3. 确认应答消息 ACK
4. 复位消息(相当于一种拒绝信息) RST
Message的可靠传输
Client构造Con Msg 发送到Server,未收到ACK或Reset时,支持基于指数回退的重发;
注释:客户端发送消息到服务端,需要等待服务器收到通知, 如果在规定时间内没有收到确认消息(ACK)或者复位消息(RST),需要重新发送数据。
Server如果可以处理该Message,返回ACK,否则返回Reset
注释:可靠传输是基于CON消息传输的,服务器端收到CON类型的消息后,如果服务器可以处理这个消息,需要返回ACK消息,客户端到在指定时间ACK_TIMEOUT内收到ACK消息后,才代表这个消息已可靠到服务器端,不能处理的话就Rejecting一个消息,一般是返回Reset或者忽略它。
Message的可靠传输
注释:**为幂运算符
Message的非可靠传输
Client对于不需要可靠传输的Message通过Non-Confirmable Msg传递
虽然不需要ACK确认NON Msg,Server仍然可能会返回Reset给Client(比如Server不能处理这个NON msg)
注释:不可靠传输是基于NON消息传输的。服务器端收到NON类型的消息后,不用回复ACK消息。
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)
异步可靠响应模式(separate Response)
非可靠响应模式
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
简单的来讲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的定义
Option内容项
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。
安全
参考资料:
RFC 7252: https://datatracker.ietf.org/doc/rfc7252/?include_text=1
CoAP协议详解完整版:https://wenku.baidu.com/view/d1fb86a0dcccda38376baf1ffc4ffe473268fdc8.html