張笑非,劉 鎮(zhèn) ,滕 瑋
(1.江蘇科技大學 計算機學院,江蘇 鎮(zhèn)江 212003;2. 北京工業(yè)大學 信息學部,北京 100124 )
基于CoAP的M2M課程教學及實驗設計
張笑非1,2,劉 鎮(zhèn)1,滕 瑋1
(1.江蘇科技大學 計算機學院,江蘇 鎮(zhèn)江 212003;2. 北京工業(yè)大學 信息學部,北京 100124 )
闡述以IETF CoAP協(xié)議擴展標準RFC 7959 “CoAP塊級傳輸”中的案例作為M2M課程教學內(nèi)容,提出通過Eclipse開源項目Californium中提供的API對實驗內(nèi)容進行設計并利用JUnit框架設計CoAP塊級傳輸案例的測試用例,測試結(jié)果驗證了相應的塊級傳輸流程。
CoAP; 塊級傳輸;請求/應答對;Californium項目
當前,全國眾多高校的物聯(lián)網(wǎng)專業(yè)都開設了M2M通信技術課程,由于涉及的理論和技術框架還在發(fā)展中,教學及實驗內(nèi)容也在不斷建設和完善中。CoAP是一種應用于受限節(jié)點和受限網(wǎng)絡的Web傳輸協(xié)議,類似HTTP但又不是盲目地在HTTP的技術上進行縮減,而是針對M2M應用進行優(yōu)化,實現(xiàn)REST架構(gòu)風格的一個子集[1]。在物聯(lián)網(wǎng)應用中,CoAP成為HTTP的替代者而實現(xiàn)智能硬件到Web的接入[2]。CoAP的標準已在IETF RFC 7252中給出,文獻[3]提出將RFC標準文檔應用于計算機網(wǎng)絡教學中。MIT、Apache等機構(gòu)也都給出了多種編程語言版本的CoAP實現(xiàn),且文獻[4-6]也提出網(wǎng)絡編程在提高教學和實驗效果方面的作用,文獻[7]分別就案例分解和重構(gòu)在網(wǎng)絡編程教學中的應用與改革進行了說明。這些都為在物聯(lián)網(wǎng)專業(yè)的M2M通信技術課程中準備了充足的教學和實驗素材。
本教學設計使用IETF RFC 7959[8]作為M2M通信技術課程中CoAP的教學內(nèi)容。RFC 7959是對RFC 7252的更新,是對CoAP塊級傳輸方式的定義。CoAP消息的基本傳輸方式是在客戶端和服務端之間,通過一次請求/應答對完成,可以滿足從傳感器讀取數(shù)據(jù),或向執(zhí)行器發(fā)送指令等小型載荷需求,但面對固件更新這種需要承載大型載荷的M2M應用時,就需要對這些載荷進行分割。由于CoAP使用的傳輸層協(xié)議是UDP或DTLS,因此不能像TCP對HTTP消息一樣進行分割和重新排列。RFC 7959在不考慮使用IP碎片機制的情況下,通過對CoAP協(xié)議增加一對Block選項的方式,對單個大型載荷進行分塊、并通過多次請求/應答對完成傳輸。
教學設計中之所以選擇RFC 7959定義的CoAP塊級傳輸作為教學內(nèi)容,是因為對于協(xié)議三要素(語法、語義、時序)而言,RFC 7252中介紹的單次請求/應答對作為時序部分較為簡單。而基于塊級傳輸?shù)亩啻握埱?應答過程,能夠幫助學生更好地理解CoAP消息在客戶端/服務端之間的交換過程;同時也可以對比受限網(wǎng)絡環(huán)境和常規(guī)互聯(lián)網(wǎng)環(huán)境下,由于需求差異導致協(xié)議棧的每一層功能和策略存在的差別。
CoAP塊級傳輸中需要利用塊選項(Block Option),塊選項分為Block1和Block2。CoAP中的請求/應答對,其中請求消息由客戶端發(fā)送給服務端,應答消息由服務端返還給客戶端。若需進行分塊的載荷來自客戶端,如PUT和POST操作,則塊選項為Block1。若需進行分塊的載荷來自服務端,如接收到GET操作,則塊選項為Block2。塊選項是變長的,可以是1個或2個或3個字節(jié)。塊選項包含3個字段,即NUM、M和SZX,其中NUM的長度可以是4bit或12bit或20bit,是當前塊在所屬載荷分割出的多個塊中的序列號;M占1bit,1表示還有后續(xù)塊,0表示本塊是最后一個;SZX占3bit,是當前塊尺寸的指數(shù),2^(SZX+4)就是當前塊的字節(jié)數(shù)。為了便于講解,后面的例子中會將塊選項寫成4個部分,即“塊選項類型:NUM/M/2**(SZX+4)”,例如:2:2/0/32表示一個Block2塊選項,塊序號為2、沒有后續(xù)塊、當前塊的長度是32字節(jié);1:3/1/128表示一個Block1塊選項,塊序號為3,還有后續(xù)塊,當前塊的長度是128字節(jié)。
RFC 7959的第3節(jié)給出4類案例,每類案例中包含若干具體案例,見表1。這些案例涵蓋了塊級GET、塊級PUT/POST的消息交換過程,其中塊級PUT與塊級POST的消息交換過程是一樣的,它們的區(qū)別在于對原子性和冪等性上的要求不一樣。這些案例演示了基本的塊級轉(zhuǎn)發(fā)流程、存在重傳的塊級轉(zhuǎn)發(fā)流程,存在塊尺寸協(xié)商的塊級轉(zhuǎn)發(fā)流程。
表1 CoAP塊級傳輸案例
如圖1,該案例給出一個GET請求被分解為三次請求/應答對,客戶端在第一次向服務端發(fā)起CoAP GET消息時,并不知道服務端將要返回的載荷大小。服務端在第一次應答中建議的塊尺寸是128字節(jié),并且M標志位為1,說明還有后續(xù)的塊。于是客戶端繼續(xù)向服務端發(fā)送GET請求,直到接收到的來自服務端的第3個應答時,由于M標志位為0,說明整個載荷接收完畢。本案例中由于來自服務端的載荷被分割成3個塊,所以塊選項類型是Block2,3個塊的NUM依次為0、1、2,每個塊的尺寸都是128字節(jié),而實際情況中,第3個塊的長度只需滿足不小于1個字節(jié)、且不大于128字節(jié)。
圖1 簡單塊級GET的消息交換過程
如圖2,教學設計中利用該案例闡述了CoAP塊級傳輸中的兩個要素,一個是塊尺寸的后期協(xié)商,另一個是重傳機制。案例中CoAP消息過程包含5個請求/應答對,這可以通過MID的值或塊選項字段NUM看出。MID是CoAP首部中的消息標示符,該例中MID從1234到1238共5個;同樣,NUM字段在5次請求/應答對中分別是0、2、3、4、5共5個,而沒有1,這正是后期協(xié)商造成的。
圖2 存在CON消息丟失的后期協(xié)商塊級GET的消息交換過程
客戶端和服務端可以在消息交換中的多次修改塊尺寸,提供類似TCP的擁塞控制功能[9]。在教學設計中,首先要講解什么是早期協(xié)商,即在第一次請求/應答對的請求消息中,如果塊選項的SZX被設置了值,那這個值就是客戶端期望服務端在后續(xù)應答時設置的塊尺寸指數(shù),反之則說明客戶端沒有進行早期協(xié)商。第一次請求/應答對中的應答消息到達客戶端后,客戶端對服務端設置的塊尺寸128字節(jié)并不滿意,因此在第二次的請求/應答對的請求消息將塊尺寸設置為64字節(jié)。由于第一次應答,服務端已經(jīng)返回了128字節(jié),而這時客戶端設置的塊尺寸為64字節(jié),因此相當于之前已經(jīng)發(fā)送了兩個64字節(jié)的塊,第二次應答消息中的塊相當于是第3個64字節(jié)了,這就是為什么轉(zhuǎn)發(fā)過程中沒有出現(xiàn)NUM為1的情況。
其次,在這個案例中,還需要對CoAP的重傳機制作講解。CoAP請求/應答對的可靠性是通過設置請求消息中的Type字段為“需確認”、即CON,客戶端會通過計時器判斷在規(guī)定時間內(nèi)是否收到與請求消息MID相同的應答消息,否則會重新發(fā)送同樣的請求消息。該案例中模擬了第二次請求/應答對的請求消息丟失的情況,若是應答消息丟失則仍由客戶端重新發(fā)送請求,服務端并不設置超時機制。
如圖3,教學設計中利用該案例闡述了CoAP塊級傳輸中的兩個要素,一個是原子性塊級傳輸,另一個是Block1和Block2塊選項的組合。整個CoAP消息過程包含6個請求/應答對,即該例中MID從1234到1239;過程的前半部分是客戶端通過Block1塊選項把發(fā)送給服務端的數(shù)據(jù)分成了3個塊依次傳輸,過程的后半部分是服務端通過Block2塊選項把返回給客戶端的結(jié)果分成了4個塊依次傳輸。由于在第3次請求/應答對中通過雙工的方式同時完成了最后一個Block1塊和第一個Block2塊,所以雙方交換7個塊通過6次請求/應答對便完成了。
圖3 原子性塊級POST/塊級應答組合的消息交換過程
在教學設計中,首先要講解原子性塊級傳輸?shù)臋C制,與之相對的是無狀態(tài)塊級傳輸。它們的區(qū)別在于在服務端通過應答消息的M字段,以表示塊級傳輸過程中的所有請求/應答對構(gòu)成一個原子性操作,還是說每個請求/應答對構(gòu)成獨立的操作。從本案例塊級傳輸?shù)拿恳淮螒鹣⒖梢钥吹?,除了最后一次應答消息,之前應答消息的M字段均為1,說明服務端預期來自客戶端更多的請求消息,直到最后一次應答消息M字段為0,表示服務端認為之前接收到的所有請求/應答對成了一次原子性的塊級傳輸過程。而在無狀態(tài)塊級傳輸中,即使客戶端發(fā)送的請求消息中通過M字段置1、以告知服務端本次請求/應答對后還有更多的請求/應答對,但服務端每次向客戶端發(fā)送的應答消息的M字段都為0,以表示服務端可以獨立處理這些被分割的塊,每一個請求/應答對是獨立的。
其次,在這個案例中,還需要對CoAP的Block1和Block2塊選項組合機制作講解。整個塊級傳輸過程共包含6次請求/應答對,其中第3次請求/應答對的應答消息中同時包含了Block1和Block2塊選項。這是因為客戶端通過前三次請求將輸入數(shù)據(jù)提交給了服務端,而服務端則在第三次應答中通過Block1塊選項M字段為0表示數(shù)據(jù)接收完成、同時還通過Block2塊選項開始向客戶端返回結(jié)果,直到第6次應答通過Block2塊選項M字段置0告知客戶端結(jié)果返回完畢。
本實驗設計使用Eclipse開源項目Californium[10]作為CoAP的實驗環(huán)境。Californium是一個面向后臺服務和強勁IoT設備的CoAP框架,其為RESTful Web服務提供的API支持CoAP的所有特性。實驗設計在Californium中將每個案例編寫成JUnit測試單元來驗證,文獻[11]就如何將JUnit應用到課程教學中做了探討。
由于每一個CoAP案例的測試設計都包含通用模塊和獨立模塊,因此在設計上利用JUnit4的標注機制。如圖4所示,用@BeforeClass定義CoAP網(wǎng)絡參數(shù)初始化函數(shù)init( ),用@Before定義CoAP客戶端實例和服務端實例的創(chuàng)建函數(shù)setupEndpoints( ),用@After定義CoAP客戶端實例和服務端實例的銷毀函數(shù)shutdownEndpoints( ),用@Test分別定義三個塊級傳輸過程函數(shù)testGET()、testGETLateNegotionalLostACK()、testAtomicBlo ckwisePOSTWithBlockwiseResponse()。
圖4 實驗測試流程
鎖步(Lockstep)也稱為時鐘同步,是一種容錯技術[12]。為了能夠重現(xiàn)教學案例中的場景,我們將服務端運行在正常模式,而將客戶端運行在鎖步模式,即客戶端每次發(fā)送和等待接收,都是通過明確的命令來控制。因此,首先定義測試用例的靜態(tài)初始化函數(shù)init( ),在其中為CoAP服務端定義運行時的網(wǎng)絡參數(shù):
接著就需要定義每次Test實例的初始化函數(shù)setupEndpoints( ),其中需要創(chuàng)建并啟動運行在正常模式的CoAP服務端實例,以及運行在鎖步模式的CoAP客戶端實例:
最后定義每次Test實例運行完畢時執(zhí)行的銷毀函數(shù)shutdownEndpoints( ):
教學設計中的3個案例,可以通過CoAP客戶端的鎖步模式完成相應的塊級傳輸流程。其中,客戶端client通過函數(shù)sendRequest完成請求消息的發(fā)送、通過函數(shù)expectResponse確認應答消息的接收。以案例3為例,為了完成圖3中的塊級傳輸流程,先通過函數(shù)generateRandomPayload為CoAP兩端生成指定長度的隨機載荷;另外,CoAP客戶端需要指定token作為區(qū)分并發(fā)請求消息的標識符,以及path作為POST請求創(chuàng)建資源的路徑。
案例3中的6次請求/應答對,每一次請求/應答對在CoAP客戶端鎖步模式下、通過執(zhí)行一對sendRequest和expectResponse函數(shù)來完成測試。
將通用模塊和案例3獨立模塊的組合作為JUnit單元測試,圖5中的運行結(jié)果正確驗證了案例3在教學設計上的塊級傳輸流程。
圖5 案例3的JUnit單元測試結(jié)果
該設計方法可以被用到M2M課程其他知識點,或者其他課程的教學和實驗設計當中去,特別是目前一些涉及新技術的物聯(lián)網(wǎng)專業(yè)課程,在實際的教學過程中讓學生掌握先進技術的原理和開發(fā)方法,以提高他們的專業(yè)素質(zhì)和能力。
[1] Shelby K S, Hartke C B.The Constrained Application Protocol (CoAP), IETF RFC 7252, June 2014[EB/OL]. [2017-06-16].https://tools.ietf.org/pdf/rfc7252.pdf.
[2] Lev? T, Mazhelis O, Suomi H. Comparing the cost-efficiency of CoAP and HTTP in Web of Things applications[J]. Decision Support Systems, 2014, 63(3): 23-38.
[3] 王盛邦, 田海博. RFC在網(wǎng)絡協(xié)議教學中的應用[J]. 現(xiàn)代計算機(專業(yè)版), 2013(23): 35-39.
[4] 張曉明, 杜天蒼, 秦彩云. 計算機網(wǎng)絡編程課程的教學改革與實踐[J]. 實驗技術與管理, 2010(2): 4-7.
[5] 胡靜, 趙雷, 羅宜元, 等. 網(wǎng)絡工程專業(yè)的網(wǎng)絡編程課程教學與改革[J]. 計算機教育, 2014(18): 35-38.
[6] 戚平, 石樂義. 原始套接字編程在網(wǎng)絡實驗教學中的應用[J]. 實驗室研究與探索, 2012(7): 325-327.
[7] 吳杰, 梁妍. 基于實驗案例分解和重構(gòu)的Android網(wǎng)絡編程教學改革探索[J]. 信息技術與信息化, 2016(5): 103-110.
[8] Borman C. Shelby Z.Block-Wise Transfers in the Constrained Application Protocol (CoAP), IETF RFC 7959, August 2016[EB/OL].[2017-06-16]. https://tools.ietf.org/pdf/rfc7959.pdf.
[9] Castellani A P, Rossi M, Zorzi M. Back pressure congestion control for CoAP/6LoWPAN networks[J]. Ad Hoc Networks, 2014,18(1):71-84.
[10] Kovatsch M, Lanter M, Shelby Z. Californium: Scalable cloud services for the Internet of Things with CoAP[C]// Internet of Things. IEEE, 2014: 1-6.
[11] 朱冬玲. JUnit在軟件測試課程教學中的應用[J]. 福建電腦, 2013(10): 56-57.
[12] 付愛英,周晶晶. 基于Lockstep的容錯技術的研究[J]. 科技廣場, 2012(7): 70-73.
1672-5913(2017)11-0150-05
G642
江蘇科技大學2016高教研究立項課題(GJKTY201625);江蘇省教育科學“十二五”規(guī)劃2015年度立項課題(D/2015/01/78);江蘇科技大學2015年學校重點教改課題“計算機類專業(yè)通用課程優(yōu)質(zhì)教學資源建設的研究與實踐”。
張笑非,男,講師,研究方向為通信技術研究與教學工作,julychang@just.edu.cn。
(編輯:郭田珍)