CoAP 协议分析与测试

1 CoAP 协议

CoAP(Constrained Application Protocol )协议是物联网中,一种轻量级的 Web 协议,类似于互联网中的 HTTP 协议。鉴于物联网设备资源受限,所以使用 CoAP 协议是一种较好的选择。CoAP 基于 UDP 协议,为了弥补 UDP 传输的不可靠性,CoAP 定义了带有重传机制的事务处理机制。

相对于 HTTP,CoAP 有如下特点

  • CoAP 采用二进制报文头,而非文本
  • CoAP 减少了协议头的类型
  • CoAP 只支持一些重要的请求方法:POST、GET、PUT、DELETE
  • CoAP 可以支持检测装置

CoAP 协议在 TCP/IP 协议栈中的位置

1.1 CoAP URL

在 HTTP 的世界中,RESTFul 协议由于其简单性和适用性,在 WEB 应用中越来越受欢迎,这样的道理同样适用于 CoAP。一个 CoAP 资源可以被一 个URI 所描述,例如一个设备可以测量温度,那么这个温度传感器的URI被描述为:CoAP://machine.address:5683/sensors/temperature。CoAP的默认 UDP 端口号为5683。

1.2 CoAP 订阅/观察模式

当我们需要去监控某个传感器例如温度或湿度等,CoAP客户端并不需要不停的查询 CoAP服务器端的数据变化情况。CoAP 提供了一种观察模式,可以理解为订阅模式,CoAP客户端可以发送一个观察请求到服务器端。从该时间点开始计算,服务器便会记住客户端的连接信息,一旦温度发生变化,服务器将会把新结果发送给客户端。如果客户端不在希望获得温度检测结果,那么客户端将会发送一个 RST 复位请求,此时服务器便会清除与客户端的连接信息。

1.3 CoAP 报文格式

CoAP 协议默认端口是 5683,报文格式如下 1

  • Ver【版本version】版本号
  • T【消息类型 Message Type】CON,NON,ACK,RST
  • TKL【Token Length】令牌长度
  • Code【功能码/响应码】Code在CoAP请求报文和响应报文中具有不同的表现形式,Code占一个字节,它被分成了两部分,前3位一部分,后5位一部分,为了方便描述它被写成了c.dd结构。其中0.XX表示CoAP请求的某种方法,而2.XX、4.XX或5.XX则表示CoAP响应的某种具体表现
  • Message ID【消息ID】每个CoAP消息都有一个ID,重发的 MID 不变
  • Token【令牌】将响应与请求匹配
  • Options【选项】CoAP选项类似于HTTP请求头,它包括CoAP消息本身,例如CoAP端口号,CoAP主机和CoAP查询字符串等
  • Payload【负载】实际携带的数据内容

1.4 Message Type(资源请求/响应模型 )

Coap 协议与 HTTP 一样,采用请求——响应的工作模式,分为 CON NON ACK RST 四种:

1 Confirmable Message —— 需要被确认的请求,发送 CON 类型的请求,必须得到响应,类似于 TCP 连接,确保数据的可靠性

                        Client              Server
                           |                  |
                           |   CON [0x7d34]   |
                           +----------------->|
                           |                  |
                           |   ACK [0x7d34]   |
                           |<-----------------+
                           |                  |

2 Non-confirmable Message ——不需要被确认的请求。发送 NON 请求,对方不必回应,适用于频繁重复发送的场景,丢包不影响正常工作,类似于 UDP 连接

                        Client              Server
                           |                  |
                           |   NON [0x01a0]   |
                           +----------------->|
                           |                  |

3 Acknowledgement Message —— 应答消息,接受到 CON 消息的响应

4 Reset Message —— 复位消息,当接收者接受到的消息包含一个错误,接受者解析消息或者不再关心发送者发送的内容,那么复位消息将会被发送

比如某个设备需要从服务器端查询当前温度信息

请求消息(CON): GET /temperature , 请求内容会被包在CON消息里面
响应消息 (ACK): 2.05 Content “22.5 C” ,响应内容会被放在ACK消息里面

1.5 Code

CoAP 报文中的 Code 字段分为两部分:0.00,类似于 HTTP 的状态码 2

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

CoAP 请求 code 如下

  • 【0.01】GET方法——用于获得某资源
  • 【0.02】POST方法——用于创建某资源
  • 【0.03】PUT方法——用于更新某资源
  • 【0.04】DELETE方法——用于删除某资源

CoAP 响应的 code 类型更为丰富,与 HTTP 响应码类似

  • 【2.01】Created
  • 【2.02】Deleted
  • 【2.03】Valid
  • 【2.04】Changed
  • 【2.05】Content。类似于HTTP 200 OK
  • 【4.00】Bad Request 请求错误,服务器无法处理。类似于HTTP 400
  • 【4.01】Unauthorized 没有范围权限。类似于HTTP 401
  • 【4.02】Bad Option 请求中包含错误选项
  • 【4.03】Forbidden 服务器拒绝请求。类似于HTTP 403
  • 【4.04】Not Found 服务器找不到资源。类似于HTTP 404
  • 【 4.05】Method Not Allowed 非法请求方法。类似于HTTP 405
  • 【4.06】Not Acceptable 请求选项和服务器生成内容选项不一致。类似于HTTP 406
  • 【4.12】Precondition Failed 请求参数不足。类似于HTTP 412
  • 【4.15】Unsuppor Conten-Type 请求中的媒体类型不被支持。类似于HTTP 415
  • 【5.00】Internal Server Error 服务器内部错误。类似于HTTP 500
  • 【5.01】Not Implemented 服务器无法支持请求内容。类似于HTTP 501
  • 【5.02】Bad Gateway 服务器作为网关时,收到了一个错误的响应。类似于HTTP 502
  • 【5.03】Service Unavailable 服务器过载或者维护停机。类似于HTTP 503
  • 【5.04】Gateway Timeout 服务器作为网关时,执行请求时发生超时错误。类似于HTTP 504
  • 【5.05】Proxying Not Supported 服务器不支持代理功能

1.6 Option

CoAP 支持多个 Option,CoAP 的 Option 的表示方法比较特殊,采用增量的方式描述,Option 格式如下

在这里插入图片描述
Option 部分包含 Option Delta、Option Length 和 Option Value 三部分,

  • 【Option Delta】表示 Option 的增量,当前的 Option 的具体编号等于之前所有 Option Delta 的总和
  • 【Option Length】表示 Option Value 的具体长度
  • 【Option Value】表示 Option 具体内容

Option 具体内容

   +-----+---+---+---+---+----------------+--------+--------+----------+
   | No. | C | U | N | R | Name           | Format | Length | Default  |
   +-----+---+---+---+---+----------------+--------+--------+----------+
   |   1 | x |   |   | x | If-Match       | opaque | 0-8    | (none)   |
   |   3 | x | x | - |   | Uri-Host       | string | 1-255  | (see     |
   |     |   |   |   |   |                |        |        | below)   |
   |   4 |   |   |   | x | ETag           | opaque | 1-8    | (none)   |
   |   5 | x |   |   |   | If-None-Match  | empty  | 0      | (none)   |
   |   7 | x | x | - |   | Uri-Port       | uint   | 0-2    | (see     |
   |     |   |   |   |   |                |        |        | below)   |
   |   8 |   |   |   | x | Location-Path  | string | 0-255  | (none)   |
   |  11 | x | x | - | x | Uri-Path       | string | 0-255  | (none)   |
   |  12 |   |   |   |   | Content-Format | uint   | 0-2    | (none)   |
   |  14 |   | x | - |   | Max-Age        | uint   | 0-4    | 60       |
   |  15 | x | x | - | x | Uri-Query      | string | 0-255  | (none)   |
   |  17 | x |   |   |   | Accept         | uint   | 0-2    | (none)   |
   |  20 |   |   |   | x | Location-Query | string | 0-255  | (none)   |
   |  35 | x | x | - |   | Proxy-Uri      | string | 1-1034 | (none)   |
   |  39 | x | x | - |   | Proxy-Scheme   | string | 1-255  | (none)   |
   |  60 |   |   | x |   | Size1          | uint   | 0-4    | (none)   |
   +-----+---+---+---+---+----------------+--------+--------+----------+

CoAP协议中支持多个Option,例如

  • 第一个Option Delta=11,表示该Option表示Uri-Path(11)
  • 第二个Option Delta=1,表示该Option=1+11,表示Content-Format(12)
  • 第三个Option Delta=3,表示该Option=3+1+11,表示Uri-Query(15)

1.7 Content-Format

和 HTTP 协议一样,CoAP 支持多种媒体类型,CoAP 协议中关于媒体类型的定义比较简单,未来可能会扩展

   +--------------------------+----------+----+------------------------+
   | Media type               | Encoding | ID | Reference              |
   +--------------------------+----------+----+------------------------+
   | text/plain;              | -        |  0 | [RFC2046] [RFC3676]    |
   | charset=utf-8            |          |    | [RFC5147]              |
   | application/link-format  | -        | 40 | [RFC6690]              |
   | application/xml          | -        | 41 | [RFC3023]              |
   | application/octet-stream | -        | 42 | [RFC2045] [RFC2046]    |
   | application/exi          | -        | 47 | [REC-exi-20140211]     |
   | application/json         | -        | 50 | [RFC7159]              |
   +--------------------------+----------+----+------------------------+
  • 【text/plain】 编号为 0,表示负载为字符串形式,默认为 UTF8 编码
  • 【application/link-format】编号为 40,CoAP 资源发现协议中追加定义,该媒体类型为CoAP 协议特有
  • 【application/xml】编号为 41,表示载荷类型为 XML 格式
  • 【application/octet-stream】编号为 42,表示负载类型为二进制格式
  • 【application/exi】编号为 47,表示负载类型为简单的 XML

2 CoAP 案例

下图显示了一个简单的 CoAP 请求与响应,CoAP 请求采用 CON 报文,因此 Server 接收到CON 报文必须返回一个 ACK 报文,ACK 报文的负载含有客户端想获取的信息。

在这里插入图片描述

CoAP 请求采用 0.01 GET 方法。如果服务端收到消息并正确处理,会返回 2.05 状态码(类似于 HTTP 200),请求和响应的 MID 必须完全相同,此处为 0x7d34。请求响应中的 Token 域为空。CoAP 请求中包含 Option,该 Option 的类型为 Uri-Path,那么 Option Delta 的值为0+11=11。下图是具体的报文内容

在这里插入图片描述

3 CoAP 协议测试

CoAP 常用的辅助测试工具如下

  • Chrome/Firefox 插件 Copper
  • Coap-cli
  • libcoap

3.1 CoAP-cli

是基于 NodeJS 的命令行工具,使用 npm(NodeJS 包管理器)即可安装,当然你首先得安装 npm(NodeJS 自带,安装 NodeJS 即可)

npm install coap-cli -g

-g 命令,添加全局变量,让我们能够在命令行中直接使用 coap 命令,接下来就可以直接使用 coap 命令进行相关操作,例如使用 coap get 访问 coap 服务器的资源

在这里插入图片描述
测试服务器地址

coap://vs0.inf.ethz.ch/
coap://iot-coap.phodal.com/id/1

3.2 libcoap

3.2.1 安装

libcoap 是一个开源的 coap 协议实现

git clone https://github.com/obgm/libcoap.git
cd libcoap
./autogen.sh
./configure --disable-doxygen --disable-manpages --disable-dtls
make
make install

configure 依据 Makefile.in 来生成一个符合惯例的 Makefile,configure 可以添加选项,防止因为系统缺少依赖而无法生成相关 Makefile 文件,比如出现以下 configure error,按照提示即可解决问题

configure: error: ==> Option '--enable-dtls' is set but none of the needed cryptography libraries GnuTLS, OpenSSL or mbed TLS could be found!
                        Install at least one of the package(s) that contains the development files for GnuTLS (>= 3.3.0), OpenSSL(>= 1.1.0), or mbed TLS(>= 2.7.10)
                        or disable the DTLS support using '--disable-dtls'.

如果想移植 libcoap,可以在配置时,添加交叉编译器的选项

./configure --host=gcc-aarch64-linux-gnu

注意:libcoap 默认会把动态链接库安装在 /usr/local/lib 目录中,系统默认加载库的路径是 /usr/lib/lib,不包含此目录,所以直接运行 coap 命令,会出现以下错误

在这里插入图片描述
将 /usr/local/lib 添加到环境变量中即可

export LD_LIBRARY_PATH=/usr/local/lib

3.2.2 使用

coap-server 创建 coap 服务端

coap-server

客户端获取数据

root@kali:~# coap-client -m get coap://localhost
This is a test server made with libcoap (see https://libcoap.net)
Copyright (C) 2010--2020 Olaf Bergmann <bergmann@tzi.org> and others

如果提示 Address already in use 如下所示

在这里插入图片描述
直接关闭占用端口的相应进程即可

在这里插入图片描述

3.3 coapper

coapper 是一个 chrome 浏览器插件 3,用于访问 coap 协议的资源。首先将 github 上的源码下载下来,解压后运行

# Windows
install.bat
# Linux
install.sh

打开 chrome 浏览器,找到扩展程序(chrome://extensions),开启 开发者模式 选项,选择 加载已解压的扩展程序,添加 coapper 源码目录中的 app 以及 extension

在这里插入图片描述
此时,在 chrome 浏览器的扩展程序界面,应该能够看到如下界面

修改 coapper 源码中的 appid,将 Copper4Cr\extension\endpoint\ClientPortChrome.js 文件中的 appid 改为上述 ID,完成安装。
在这里插入图片描述

4 附录

CoAP 协议的常用开源代码实现 4

名称开发语言CoAP版本客户端/服务端实现的CoAP特征开源协议项目链接地址
CaliforniumJavaRFC 7252Client + ServerObserve, Blockwise Transfers, DTLSEPL+EDLhttps://www.eclipse.org/californium
cantcoapC++/CRFC 7252Client + Server BSDhttps://github.com/staropram/cantcoap
CoAP implementation for GoGoRFC 7252Client + ServerCore + Draft SubscribeMIThttps://github.com/dustin/go-coap
CoAP.NETC#RFC 7252, coap-13, coap-08, coap-03Client + ServerCore, Observe, Blockwise Transfers3-clause BSDhttps://github.com/smeshlink/CoAP.NET
CoAPSharpC#, .NETRFC 7252Client + ServerCore, Observe, Block, RDLGPLhttp://www.coapsharp.com
CoAPthonPythonRFC 7252Client + Server + Forward Proxy + Reverse ProxyObserve, Multicast server discovery, CoRE Link Format parsing, Block-wiseMIThttps://github.com/Tanganelli/CoAPthon
CopperJavaScript (Browser Plugin)RFC 7252ClientObserve, Blockwise Transfers3-clause BSDhttps://github.com/mkovatsc/Copper
https://addons.mozilla.org/de/firefox/addon/copper-270430/
eCoAPCRFC 7252Client + ServerCoreMIThttps://gitlab.com/jobol/ecoap
Erbium for ContikiCRFC 7252Client + ServerObserve, Blockwise Transfers3-clause BSDhttp://www.contiki-os.org/ (er-rest-example)
ETRI CoAPCRFC 7252Client + ServerCore, Observe, BlockCommercialhttp://coap.or.kr/index_en.html
iCoAPObjective-CRFC 7252ClientCore, Observe, Blockwise TransfersMIThttps://github.com/stuffrabbit/iCoAP
jCoAPJavaRFC 7252Client + ServerObserve, Blockwise TransfersApache License 2.0https://code.google.com/p/jcoap/
libcoapCRFC 7252Client + ServerObserve, Blockwise TransfersBSD/GPLhttp://sourceforge.net/projects/libcoap/develop
microcoapCRFC 7252Client + Server MIThttps://github.com/1248/microcoap
nCoapJavaRFC 7252Client + ServerObserveBSDhttps://github.com/okleine/nCoAP
node-coapJavascriptRFC 7252Client + ServerCore, Observe, BlockMIThttps://github.com/mcollina/node-coap
Ruby coapRubyRFC 7252Client + Server (david)Core, Observe, Block, RDMIT, GPLhttps://github.com/nning/coap
https://github.com/nning/david
Sensinode C Device LibraryCRFC 7252Client + ServerCore, Observe, Block, RDCommercialhttps://silver.arm.com/browse/SEN00
Sensinode Java Device LibraryJava SERFC 7252Client + ServerCore, Observe, Block, RDCommercialhttps://silver.arm.com/browse/SEN00
Sensinode NanoService PlatformJava SERFC 7252Cloud ServerCore, Observe, Block, RDCommercialhttps://silver.arm.com/browse/SEN00
SMCPCRFC 7252Client + ServerCore, Observe, BlockMIThttps://github.com/darconeous/smcp
SwiftCoAPSwiftRFC 7252Client + ServerCore, Observe, Blockwise TransfersMIThttps://github.com/stuffrabbit/SwiftCoAP
TinyOS CoapBlipnesC/Ccoap-13Client + ServerObserve, Blockwise TransfersBSDhttp://docs.tinyos.net/tinywiki/index.php/CoAP
txThingsPython (Twisted)RFC 7252Client + ServerBlockwise Transfers, Observe (partial)MIThttps://github.com/siskin/txThings/

  1. https://tools.ietf.org/html/rfc7252 ↩︎

  2. https://blog.csdn.net/xukai871105/article/details/45167069 ↩︎

  3. https://github.com/mkovatsc/Copper4Cr ↩︎

  4. https://my.oschina.net/RainyZou/blog/1605334 ↩︎

  • 4
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

江下枫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值