1 CoAP简介

CoAP 是受限制应用协议的简称,是物联网应用层协议之一。物联网应用层协议主要还有HTTP和MQTT,这三种协议有各自不同的应用场景。其中HTTP和MQTT使用TCP作为传输层协议,而CoAP使用UDP作为传输层协议,如下图:

虽然CoAP没有使用TCP作为传输层协议,但它也是TCP/IP协议族的一部分。CoAP借鉴了大量HTTP的经验,比如CoAP也使用请求/响应工作模式(客户端发送CoAP请求,服务器侦听到该请求后根据请求内容返回响应码和相应内容)。不过与HTTP不一样的是,CoAP专门为低功耗受限制设备设计,它比HTTP简单很多。

2 CoAP快速入门

2.1 框架

通过一个简单 例子 来进行CoAP的学习,平台结构如下

安装有libcoap的Linux主机作为CoAP客户端,而 WeMos D1 作为CoAP服务器。CoAP服务器提供数量有限的几种服务,在 RESTful 风格下,这些服务被称为资源,由WeMos D1组成的CoAP服务器具有一个hello资源,通过GET方法可获得hello资源,其包含一个固定字符串内容“Hello CoAP!”,此外还提供一个light资源,该资源支持GET方法和PUT方法访问,通过GET方法可获得该资源内容,通过PUT方法可以修改该资源的内容,结合GET和PUT方法,可以把虚拟资源的操作直接映射到真实资源中【此例中light资源对应于一个真实的LED灯,其与WeMos D1的引脚2相连】。

2.2 CoAP服务器实现

从代码仓库的first_demo/microcoap目录中获取实例代码,其中

  • microcoap.ino为Arduino IDE的工程文件。
  • coap.c和coap.h为CoAP的实现代码,该部分代码实现了CoAP首部解析和填充、选项解析和填充、负载分离和填充等功能。虽然 coap.c 和 coap.h 仅实现了CoAP的一部分基础功能,但对于本例子,这两个文件并不需要修改。

2.2.1 初始化

Arduino IDE的工程文件中,总有setup()和loop()函数,这点不知道的小伙伴可以学习下Arduino IDE编程,本例中setup()用于实现LED初始化,串口初始化,网络设备初始化等,部分代码如下所示:

//宏定义WeMos D1要连接的WiFi信息
#define AP_SSID "LaoLin"
#define AP_PSW "66684403"//定义UDP变量及包缓存区域
EthernetUDP udp;
uint8_t packetbuf[256];//传感器引脚以及对应变量
static int led = 2;
static char light = '0';void setup()
{int i;pinMode(led, OUTPUT);Serial.begin(9600);Serial.println("Program is beginning");//连接WiFiWiFi.begin(AP_SSID, AP_PSW);Serial.print(String("Connecting to ")+AP_SSID);while (WiFi.status() != WL_CONNECTED){delay(500);//Serial.print(".");}Serial.print("\nConnected, IP address: ");//输出当前IP地址Serial.println(WiFi.localIP());//侦听5683端口的UDP输入数据udp.begin(5683);build_rsp();
}

2.2.2 CoAP数据处理

CoAP数据处理位于loop()函数内,处理流程如图所示:

具体代码如下所示:

void udp_send(const uint8_t *buf, int buflen)
{udp.beginPacket(udp.remoteIP(), udp.remotePort());while(buflen--)udp.write(*buf++);udp.endPacket();
}
void loop()
{int sz;int rc;coap_packet_t pkt;int i;if ((sz = udp.parsePacket()) > 0){//读取UDP请求内容udp.read(packetbuf, sizeof(packetbuf));for (i = 0; i < sz; i++){Serial.print(packetbuf[i], HEX);Serial.print(" ");}Serial.println("");//验证解析CoAP请求if (0 != (rc = coap_parse(&pkt, packetbuf, sz))){//CoAP数据包有问题Serial.print("Bad packet rc=");Serial.println(rc, DEC);}else{size_t rsplen = sizeof(packetbuf);coap_packet_t rsppkt;//处理CoAP请求coap_handle_req(&scratch_buf, &pkt, &rsppkt, endpoints);memset(packetbuf, 0, UDP_TX_PACKET_MAX_SIZE);//构造CoAP响应if (0 != (rc = coap_build(packetbuf, &rsplen, &rsppkt))){//CoAP响应构造失败Serial.print("coap_build failed rc=");Serial.println(rc, DEC);}else{//返回UDP数据包udp_send(packetbuf, rsplen);}}}
}

2.2.3 资源列表

endpoints列表是一组资源集合,当WeMos D1服务器收到CoAP请求时将遍历此资源集合,其中每个资源都由请求方法,请求处理函数,请求URI和媒体类型组成,具体代码如下:

coap_endpoint_t endpoints[] =
{{COAP_METHOD_GET, handle_get_well_known_core, &path_well_known_core, "ct=40"},{COAP_METHOD_GET, handle_get_hello, &path_hello, "ct=0"},{COAP_METHOD_GET, handle_get_light, &path_light, "ct=0"},{COAP_METHOD_PUT, handle_put_light, &path_light, NULL},{(coap_method_t)0, NULL, NULL, NULL}
};
2.2.3.1 hello 资源

资源定义需要两部分组成,分别是URI和请求处理函数,其代码如下:

//URI,可通过coap://IP/hello对该资源进行访问
static const coap_endpoint_path_t path_hello = {1, {"hello"}};
//请求处理函数
static int handle_get_hello(coap_rw_buffer_t *scratch, const coap_packet_t *inpkt, coap_packet_t *outpkt, uint8_t id_hi, uint8_t id_lo)
{char hello[32] = "Hello CoAP!";return coap_make_response(scratch, outpkt, (const uint8_t *)&hello, strlen(hello), id_hi, id_lo, &inpkt->tok, COAP_RSPCODE_CONTENT, COAP_CONTENTTYPE_TEXT_PLAIN);
}
2.2.3.2 light 资源

light资源与hello资源类似,其PUT方法的处理函数代码如下:

static int handle_put_light(coap_rw_buffer_t *scratch, const coap_packet_t *inpkt, coap_packet_t *outpkt, uint8_t id_hi, uint8_t id_lo)
{if (inpkt->payload.p[0] == '1'){//CoAP请求的payload字段为1,则点亮LED灯light = '1';digitalWrite(led, HIGH);Serial.println("ON");}else{//CoAP请求的payload字段为0,则熄灭LED灯light = '0';digitalWrite(led, LOW);Serial.println("OFF");}return coap_make_response(scratch, outpkt, (const uint8_t *)&light, 1, id_hi, id_lo, &inpkt->tok, COAP_RSPCODE_CHANGED, COAP_CONTENTTYPE_TEXT_PLAIN);
}

2.3 测试

使用已安装有libcoap的Linux主机对WeMos D1服务器发起访问,使用以下命令分别对资源进行访问:

./coap-client -m get coap://[ip]/hello
./coap-client -m get coap://[ip]/light
./coap-client -m put -e "1" coap://[ip]/light

3 CoAP核心

CoAP协议的核心部分内容包括如下内容:

  • CoAP首部分析:版本编号、报文类型、标签长度指示、准则、报文序号、标签、选项、分隔符和负载。
  • CoAP工作模式说明:CON、NON、ACK和RST。
  • CoAP重传机制分析:CoAP请求丢失处理、CoAP响应丢失处理、最大重传次数、最大传输耗时、最大等待时间。
  • CoAP方法说明:GET方法、POST方法、PUT方法和DELETE方法。
  • CoAP响应码说明:正确响应、客户端错误、服务器错误。
  • CoAP选项详细分析:选项格式、URI选项、Content-Format选项、Accept选项、Etag选项、If-Match选项、If-None-Match选项。
  • CoAP媒体类型说明:link-format类型、文本类型、二进制类型、JSON类型。

由于网上本部分资料比较多,博主就不再重复,如有需要了解,找不到好的资料的,也可以下载博客最后面分享的书籍资料进行学习。

4 遇到的问题

  • 刚开始学习CoAP,上网找到的资料基本上说的都是概念性的东西,项目类博客也说的云里雾里,不知道怎么动手操作一个实质性的项目,后来找到了这本书《IoT开发实战:CoAP卷》,PDF的下载链接放在超链接中,有需要的朋友可以自行下载,若是链接失效,可以留言提醒。不得不说要系统性的学习一门知识,还是书籍更好点。
  • 各位看官有问题请留言。

一个用来学习CoAP协议的小例子相关推荐

  1. 【Pthon入门学习】多级菜单小例子

    1 menu_list = { 2 '北京':{ 3 '昌平':{ 4 '回龙观':{ 5 '和谐家园':{}, 6 '矩阵小区':{}, 7 '北店家园':{} 8 }, 9 '沙河':{ 10 ' ...

  2. CoAP协议学习笔记 1.3 用UDP工具来调试CoAP

    1 前言 CoAP的调试,目前没找到好用的工具,网上说的火狐插件现在也不能用了,多希望手头的TCP/UDP网络调试工具就可以支持. 既然CoAP是基于UDP来组包的,那肯定是可以实现. 所以这篇文章给 ...

  3. CoAP协议学习笔记——CoAP格式详解

    CoAP是受限制的应用协议(Constrained Application Protocol)的代名词.在当前由PC机组成的世界,信息交换是通过TCP和应用层协议HTTP实现的.但是对于小型设备而言, ...

  4. CoAP协议学习笔记 1.2 一张表了解 CoAP 协议

    1 前言 对于CoAP协议的学习,这份100多页的文档肯定没法背下来.我们只需把协议当作工具书,大体知道主体的内容,在遇到细节问题时再去具体章节找问题. 本篇笔记中先对 CoAP 协议内容做个基础了解 ...

  5. 物联网基础之了解CCP协议,COAP协议,MTQQ协议等

    首先介绍下背景.最近开始研究物联网的套件.公司选中了阿里物联网套件,所以博主就开始投入到漫长的开发文档中.由于博主并非嵌入式开发者,所以一些名字没有听过,这对文档的阅读造成了不少的困扰,所以在此记录一 ...

  6. CoAP协议学习——CoAP基础

    [原连接地址] 更多CoAP文章请参考博文索引--[物联网学习笔记--索引博文] 推广 <IoT开发实战:CoAP卷>已经由机械工业出版社出版,如果想学习CoAP的更多内容请于淘宝.天猫或 ...

  7. CoAP协议学习笔记 3.1 CoAP协议翻译 加密基础介绍

    CoAP协议学习笔记可点此查看. 1 前言 在之前的学习中,没有过多关注加密.但实际部分厂家的IoT平台(阿里云.OneNET)已经启用了相关安全处理,有必要深入学习下. 在 CoAP 协议 RFC7 ...

  8. CoAP协议学习笔记(一)

    目录 CoAP协议定义 CoAP协议特点 协议模型 Message Format Message Hader(CoAP报文结构) CoAP的响应码 Message分类 Message的可靠传输 Mes ...

  9. 物联网协议之CoAP协议开发学习笔记之术语解释

    哪有什么天生如此,只是我们天天坚持. -Zhiyuan 此文章主要总结CoAP协议的术语解释: 只在网上找到了[RFC2616] 的解释,但是这些都是通用的 本文档要求读者熟悉[RFC2616]中讨论 ...

最新文章

  1. 手把手教你搭建AI开发环境 !(附代码、下载地址)
  2. 使用深度学习和树搜索进行从零开始的既快又慢的学习
  3. 一次ajax多次回调结果,Ajax异步的回调函数执行了多遍
  4. 在集群服务器进行自定义数据集训练记录过程 TensorBoard logging requires TensorBoard with Python summary writer installed.
  5. 修改mysql 外删除用户_mysql添加用户、删除用户、授权、修改密码等
  6. 服务器imm口加载硬盘,ibm x3250 M4如何进IMM(远程管理口)
  7. Visual Studio 2017新版发布,极大提高开发效率丨附下载 1
  8. openmv识别物体并与单片机通信(STM32)
  9. 天生对数字不敏感的人,如何提升对数据的敏感度?
  10. python成功之路,Day1-发展历史
  11. 2012北理机试题——已知中序和后序遍历序列,求先序
  12. Node.js 0.8.20 稳定版发布
  13. 关于我本人阳了个阳一事
  14. trove 基本介绍
  15. c++模板(函数模板,类中函数模板,类模板)
  16. Trinity使用流程
  17. bash shell 命令 - linux
  18. 微信PC版的缓存文件夹
  19. 开源盛世 Linux 资源导航 —★—
  20. 北京理工大学 计算机学院 书院,书院交流 | 北京理工大学睿信书院来我院调研交流...

热门文章

  1. JavaCV实现视频人脸检测
  2. Python: PS 滤镜特效 -- Marble Filter
  3. 沃尔玛在华架构调整计划遭到工会反对
  4. STM32 IO口输出高低电平
  5. 生成县域级年GDP统计图
  6. go下载安装使用web框架iris + go mod使用
  7. win7开机蓝屏提示STOP:0X0000007B的解决方法
  8. ocpc系列 (三)ocpx效果到底怎么样?从ocpc与ocpm的区别说起
  9. Lua Profiler——快速定位Lua性能问题
  10. Intellij ideaIU 常用配置