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
圖片來源:HCIP-IOT Developer 培訓教材 ;CoAP協議詳解