1. 程式人生 > >抓住CoAP協議的“心”

抓住CoAP協議的“心”

![](https://james-1258744956.cos.ap-shanghai.myqcloud.com/thingsboard-coap-part2/coap-banner2.jpg) ## 摘要 **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](https://www.npmjs.com/package/coap-cli): CoAP-CLI是CoAP的命令列介面,基於node.js和[node-coap](https://github.com/mcollina/node-coap)所構建。 - [The CoAP Shell](https://github.com/tzolov/coap-shell)提供用於與CoAP協議互動的命令列介面。它支援`coap:`和`coaps`模式(例如UDP和DTLS)。CoAP Shell建立在[Spring Shell](https://projects.spring.io/spring-shell/), [Californium(Cf)](https://www.eclipse.org/californium/)和[Scandium(Sc)](https://www.eclipse.org/californium/)專案之上。它是一個[SpringBoot](https://spring.io/projects/spring-boot)應用程式,它內置於單個可自我執行的jar中,並且可以在任何**Java8+**環境中執行。 由於CoAP Shell能更好的體現和展示CoAP的功能、特性和訊息格式,接下來我將通過CoAP Shell來講述CoAP協議相關知識點。 以下是**CoAP Shell**效果圖 ![](https://james-1258744956.cos.ap-shanghai.myqcloud.com/thingsboard-coap-part2/coap-shell-demo2.gif) ### 如何構建 從GitHub克隆專案並使用Maven進行構建,或者直接從下方下載。 連結: https://pan.baidu.com/s/1soGdqIlOBQe968_wezxq7Q 密碼: rw6o ```shell git clone https://github.com/sanshengshui/coap-shell cd coap-shell mvn clean install ``` 然後在該target資料夾中執行可執行jar包。 ### 快速開始 1. 啟動Shell: ```bash java -jar coap-shell-1.1.2-SNAPSHOT.jar ``` ```bash _____ ___ ___ ______ ____ / ___/__ / _ | / _ \ / __/ / ___ / / / / /__/ _ \/ __ |/ ___/ _\ \/ _ \/ -_) / / \___/\___/_/ |_/_/ /___/_//_/\__/_/_/ CoAP Shell (v1.1.2-SNAPSHOT) For assistance hit TAB or type "help". server-unknown:> ``` 2. 連線到CoAP伺服器(例如`coap://californium.eclipse.org/`或`coap://coap.me`) ```bash server-unknown:>connect coap://coap.me available coap://coap.me:>ping available coap://coap.me:> ``` 3. 發現可用的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:> ``` 4. **GET**獲取資源資料 ```bash 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: 訊息負載資料 5. **Delete**資源資料 ```bash 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:> ``` 6. **PUT**資源資料 ```bash 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:> ``` 7. **POST**資源資料 ```bash 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](https://github.com/sanshengshui/coap-shell)。 下一篇,我將手把手帶大家用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/co