专栏首页穆书伟抓住CoAP协议的“心”

抓住CoAP协议的“心”

摘要

The Constrained Application Protocol(CoAP)是一种专用的Web传输协议,用于受约束的节点和受约束的(例如,低功率,有损)网络。

节点通常具有带少量ROM和RAM的8位微控制器,而诸如低功耗无线个人局域网 (6LoWPAN)上的IPv6之类的受限网络通常具有较高的分组错误率,典型吞吐量为10 kbps 。该协议旨在用于机器对机器(M2M)应用,例如智能能源和楼宇自动化。

CoAP提供了应用程序端点之间的请求/响应交互模型,支持服务的资源发现,并包括Web的关键概念,例如URI和Internet媒体类型。CoAP旨在轻松与HTTP交互以与Web集成,同时满足诸如多播支持,非常低的开销以及在受限环境中的简单性等特殊要求。

介绍

互联网上的Web服务(Web API)的使用在大多数应用程序中已经无处不在,并且依赖于Web 的Representational State Transfer(REST)体系结构。

Constrained RESTful Environments(CoRE)的工作旨在以最合适的形式实现REST体系结构,以适用于最受约束的节点(例如RAM和ROM受限的8位微控制器)和网络(例如6LoWPAN)。诸如6LoWPAN之类的受约束的网络支持将IPv6数据包分段成小的链路层帧。但是,这会大大减少数据包交付概率。CoAP的一个设计目标是保持消息开销较小,从而限制了分段的需要。

CoAP的主要目标之一是针对这种受限环境的特殊要求设计通用的Web协议,尤其是考虑到能源,楼宇自动化以及其他机器对机器(M2M)应用程序。

CoAP的目标不是盲目地压缩HTTP,而是实现与HTTP通用但针对M2M应用程序进行了优化的REST的子集。尽管CoAP可用于将简单的HTTP接口重新生成更紧凑的协议,更重要的是,它还提供了M2M的功能,例如内置资源发现,多播支持和异步消息交换。

该协议可以轻松转换为HTTP以与现有Web集成,同时满足特殊要求,例如多播支持,非常低的开销以及受约束环境和M2M应用程序的简便性。

特性

CoAP具有以下主要功能:

  • 在受限条件下满足M2M要求的Web协议
  • UDP [ RFC0768 ]绑定,具有可选的可靠性,支持单播和多播请求。
  • 异步消息交换。
  • 低的报头开销和解析复杂度。
  • 简单的代理和缓存功能。
  • 无状态HTTP映射,允许构建代理通过HTTP统一方式或HTTP访问CoAP资源。
  • 绑定到数据报传输层安全性(DTLS)的安全性。
  • URI和内容类型支持。

消息格式

  0                   1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |Ver| T |  TKL  |      Code     |          Message ID           |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |   Token (if any, TKL bytes) ...
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |   Options (if any) ...
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |1 1 1 1 1 1 1 1|    Payload (if any) ...
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

上图的头部字段定义如下:

Version(Ver): 2位无符号整数。CoAP版本号。本规范的实现必须将此字段设置为1(01二进制)。其他值保留用于将来的版本。

Type(T): 2位无符号整数。指示此消息的类型是否为Confirmable(0), Non-Confirmable, Acknowledgement(2)或者Reset(3)。

Token Length(TKL): 4位无符号整数。指示可变长度令牌字段的长度(0-8个字节)。长度9-15 保留,不得发送,并且必须作为消息格式错误进行处理。

Code: 8位无符号整数,响应码。

Message ID: 网络字节顺序的16位无符号整数。用于检测消息重复并将确认/重置类型的消息与可确认/不可确认类型的消息进行匹配。

CoAP初体验

CoAP有两款我觉得比较不错的客户端:

  • CoAP-CLI: CoAP-CLI是CoAP的命令行界面,基于node.js和node-coap所构建。
  • The CoAP Shell提供用于与CoAP协议交互的命令行界面。它支持coap:coaps模式(例如UDP和DTLS)。CoAP Shell建立在Spring Shell, Californium(Cf)Scandium(Sc)项目之上。它是一个SpringBoot应用程序,它内置于单个可自我执行的jar中,并且可以在任何Java8+环境中运行。

由于CoAP Shell能更好的体现和展示CoAP的功能、特性和消息格式,接下来我将通过CoAP Shell来讲述CoAP协议相关知识点。

以下是CoAP Shell效果图

如何构建

从GitHub克隆项目并使用Maven进行构建,或者直接从下方下载。

链接: https://pan.baidu.com/s/1soGdqIlOBQe968_wezxq7Q 密码: rw6o

git clone https://github.com/sanshengshui/coap-shell
cd coap-shell
mvn clean install

然后在该target文件夹中运行可执行jar包。

快速开始

  1. 启动Shell:
java -jar coap-shell-1.1.2-SNAPSHOT.jar
  _____     ___   ___     ______       ____
 / ___/__  / _ | / _ \   / __/ /  ___ / / /
/ /__/ _ \/ __ |/ ___/  _\ \/ _ \/ -_) / /
\___/\___/_/ |_/_/     /___/_//_/\__/_/_/
CoAP Shell (v1.1.2-SNAPSHOT)
For assistance hit TAB or type "help".

server-unknown:>
  1. 连接到CoAP服务器(例如coap://californium.eclipse.org/coap://coap.me)
server-unknown:>connect coap://coap.me
available
coap://coap.me:>ping
available
coap://coap.me:>
  1. 发现可用的CoAP资源
coap://coap.me:>discover
┌──────────────────────────────┬────────────────────────┬─────────────────────────┬───────────┬──────┬─────────────┐
│Path [href]                   │Resource Type [rt]      │Content Type [ct]        │Interface  │Size  │Observable   │
│                              │                        │                         │[if]       │[sz]  │[obs]        │
├──────────────────────────────┼────────────────────────┼─────────────────────────┼───────────┼──────┼─────────────┤
│/123412341234123412341234     │123412341234123412341234│text/plain (0)           │           │      │             │
│/3                            │3                       │application/json (50)    │           │      │             │
│/4                            │4                       │application/json (50)    │           │      │             │
│/5                            │5                       │application/json (50)    │           │      │             │
│/bl%C3%A5b%C3%A6rsyltet%C3%B8y│blåbærsyltetøy          │text/plain (0)           │           │      │             │
│/broken                       │Type2, Type1            │text/plain (0)           │If2, If1   │      │             │
│/create1                      │create1                 │text/plain (0)           │           │      │             │
│/hello                        │Type1                   │text/plain (0)           │If1        │      │             │
│/large                        │Type1, Type2            │text/plain (0)           │If2        │1700  │             │
│/large-create                 │large-create            │text/plain (0)           │           │      │             │
│/large-update                 │large-update            │text/plain (0)           │           │      │             │
│/location-query               │location-query          │text/plain (0)           │           │      │             │
│/location1                    │location1               │application/link-format  │           │      │             │
│                              │                        │(40)                     │           │      │             │
│/multi-format                 │multi-format            │text/plain (0)           │           │      │             │
│/path                         │path                    │application/link-format  │           │      │             │
│                              │                        │(40)                     │           │      │             │
│/query                        │query                   │text/plain (0)           │           │      │             │
│/secret                       │secret                  │text/plain (0)           │           │      │             │
│/seg1                         │seg1                    │application/link-format  │           │      │             │
│                              │                        │(40)                     │           │      │             │
│/separate                     │separate                │text/plain (0)           │           │      │             │
│/sink                         │sink                    │text/plain (0)           │           │      │             │
│/test                         │test                    │text/plain (0)           │           │      │             │
│/validate                     │validate                │text/plain (0)           │           │      │             │
│/weird33                      │weird33                 │text/plain (0)           │           │      │             │
│/weird333                     │weird333                │text/plain (0)           │           │      │             │
│/weird3333                    │weird3333               │text/plain (0)           │           │      │             │
│/weird33333                   │weird33333              │text/plain (0)           │           │      │             │
│/weird44                      │weird44                 │text/plain (0)           │           │      │             │
│/weird55                      │weird55                 │text/plain (0)           │           │      │             │
└──────────────────────────────┴────────────────────────┴─────────────────────────┴───────────┴──────┴─────────────┘

coap://coap.me:>
  1. GET获取资源数据
coap://coap.me:>get /hello
----------------------------------- Response -----------------------------------
GET coap://coap.me/hello
MID: 64187, Type: ACK, Token: 50E8F0AC1BA8D277, RTT: 3368ms
Options: {"Content-Format":"text/plain"}
Status : 205-Reset Content, Payload: 5B
................................... Payload ....................................
world
--------------------------------------------------------------------------------

从以上列表能清晰的看出CoAP的消息格式和数据包。

  • coap://coap.me/hello : 是CoAP协议的uri
  • MID: 消息的ID,用于唯一区分消息。
  • Type: 消息类型,这里的消息类型为:Acknowledgement(确认)
  • Token: 消息会话
  • Options:{"Content-Format":"text/plain"}消息可选性,这里表示消息的数据类型为文本
  • Status: 状态码
  • Payload: 消息负载数据
  1. Delete资源数据 coap://coap.me:>get /sink NULL response! coap://coap.me:>delete /sink ----------------------------------- Response ----------------------------------- DELETE coap://coap.me/sink MID: 64264, Type: ACK, Token: 0C2338F7FB9447F7, RTT: 274ms Options: {"Content-Format":"text/plain"} Status : 202-Accepted, Payload: 9B ................................... Payload .................................... DELETE OK -------------------------------------------------------------------------------- coap://coap.me:>get /sink ----------------------------------- Response ----------------------------------- GET coap://coap.me/sink MID: 64265, Type: ACK, Token: 04A8DACB450186A7, RTT: 276ms Options: {"ETag":0xa6166ef62ce0b4bc, "Content-Format":"text/plain"} Status : 205-Reset Content, Payload: 38B ................................... Payload .................................... I was deleted, and you put here: hello -------------------------------------------------------------------------------- coap://coap.me:>
  2. PUT资源数据 coap://coap.me:>put /sink --payload 'Hi From IoT Technology' --format text/plain ----------------------------------- Response ----------------------------------- PUT coap://coap.me/sink MID: 64266, Type: ACK, Token: FC2CE751AD5A232A, RTT: 368ms Options: {"Content-Format":"text/plain"} Status : 204-No Content, Payload: 6B ................................... Payload .................................... PUT OK -------------------------------------------------------------------------------- coap://coap.me:>get /sink ----------------------------------- Response ----------------------------------- GET coap://coap.me/sink MID: 64267, Type: ACK, Token: 3439364639206648, RTT: 13478ms Options: {"ETag":0x01fd3e1298b1fb7a, "Content-Format":"text/plain"} Status : 205-Reset Content, Payload: 36B ................................... Payload .................................... you put here: Hi From IoT Technology -------------------------------------------------------------------------------- coap://coap.me:>
  3. POST资源数据
coap://coap.me:>delete /sink
----------------------------------- Response -----------------------------------
DELETE coap://coap.me/sink
MID: 64268, Type: ACK, Token: 0CCB572626A124A6, RTT: 391ms
Options: {"Content-Format":"text/plain"}
Status : 202-Accepted, Payload: 9B
................................... Payload ....................................
DELETE OK
--------------------------------------------------------------------------------
coap://coap.me:>post /sink --payload 'testing for post data' --format text/plain
----------------------------------- Response -----------------------------------
POST coap://coap.me/sink
MID: 64269, Type: ACK, Token: A441392CC855852D, RTT: 424ms
Options: {"Location-Path":["location1","location2","location3"], "Content-Format":"text/plain"}
Status : 201-Created, Payload: 7B
................................... Payload ....................................
POST OK
--------------------------------------------------------------------------------
coap://coap.me:>get /sink
----------------------------------- Response -----------------------------------
GET coap://coap.me/sink
MID: 64270, Type: ACK, Token: DC24713232F17DB7, RTT: 325ms
Options: {"ETag":0xf97973ea26db6781, "Content-Format":"text/plain"}
Status : 205-Reset Content, Payload: 54B
................................... Payload ....................................
I was deleted, and you put here: testing for post data
--------------------------------------------------------------------------------

到此为止,我相信大家对CoAP协议的消息格式应该有了一定的认知。更多信息和使用请浏览这个库的README

下一篇,我将手把手带大家用Eclipse Californium搭建CoAP Server服务。

参考资料

CoAP英文官方文档: https://tools.ietf.org/html/rfc7252

CoAP Wiki百科: https://en.wikipedia.org/wiki/Constrained_Application_Protocol

CoAP-Shell客户端: https://github.com/sanshengshui/coap-shell

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 物联网时代-跟着Thingsboard学IOT架构-CoAP设备协议

    演示视频请移步: https://james-1258744956.cos.ap-shanghai.myqcloud.com/thingsboard/coap...

    sanshengshui
  • Netty实现高性能IOT服务器(Groza)之手撕MQTT协议篇上

    MQTT由Andy Stanford-Clark(IBM)和Arlen Nipper(Eurotech,现为Cirrus Link)于1999年开发,用于监测穿...

    sanshengshui
  • 简述RPC原理实现

    随着业务规模的扩张,为了满足业务对技术的要求,技术架构需要从单体应用架构升级到分布式服务架构,来降低公司的技术成本,更好的适应业务的发展。

    sanshengshui
  • 米斯特白帽培训讲义(v2)实战篇 迅雷 CMS

    起因是这样,我们随便找了一个网站,访问后台登录页面(/admin/login.asp),然后使用弱密码admin:admin进了后台(/admin/index....

    ApacheCN_飞龙
  • 工作--如何封装第三方服务?

    业务开发中经常会对接某某第三方服务,因此会经常写一些SDK供服务使用,一种比较好的做法就是使用命令模式封装第三方服务,命令模式对于调用方来说简洁明了,也正是封装...

    屈定
  • 操作系统基础-内存虚拟化

    原文发布于微信公众号 - 云服务与SRE架构师社区(ai-cloud-ops),作者李勇。

    王录华
  • 干货 | PCB设计规范其实就是“怎么摆”和“怎么连”!

    PCB设计纷繁复杂,各种意料之外的因素频频来影响整体方案的达成,如何能驯服性格各异的零散部件?怎样才能画出一份整齐、高效、可靠的PCB图?今天就让我们来盘点一下...

    MCU起航
  • 项目分布式部署那些事(1):ONS消息队列、基于Redis的Session共享,开源共享

    因业务发展需要现在的系统不足以支撑现在的用户量,于是我们在一周之前着手项目的性能优化与分布式部署的相关动作。 概况 现在的系统是基于RabbitHub(一套开源...

    逸鹏
  • 闲扯Tick Tock

    这两天心情不好,留言可能回得简单了些,文章也写得不那么在状态,大家包容一下吧。 昨天早上终于了结了最近两周多一直忙碌的事情,下周起应该不用每天早上七八点开会了。...

    tyrchen
  • jquery getJSON不执行问题解决

    你可以在原回调函数里面加句alert(“回调成功”) , 来确定一下是否调用了回调函数,如果没有调用,则仔细检查你的JSON数据格式

    莫斯

扫码关注云+社区

领取腾讯云代金券