田文武
伴隨著Internet技術(shù)在全球范圍內(nèi)的日益普及,諸多基于互聯(lián)網(wǎng)架構(gòu)的新業(yè)務(wù)正如雨后春筍般涌現(xiàn),VoIP(Voice over IP)就是一種典型的互聯(lián)網(wǎng)新興技術(shù)。和傳統(tǒng)的電路交換通信技術(shù)相比,VoIP技術(shù)以IP數(shù)據(jù)包的形式,傳輸通信過程中,產(chǎn)生的所有信令與實時音視頻數(shù)據(jù),從而可以實現(xiàn)更為低廉的通訊成本。同時,由于基于開放的IP網(wǎng)絡(luò)架構(gòu),結(jié)合當前最新的處理器芯片和嵌入式操作系統(tǒng)技術(shù),VoIP終端可以實現(xiàn)許多傳統(tǒng)電話無法提供的新應(yīng)用,如傳真、視頻、數(shù)據(jù)等,最終為用戶提供更為便利的通信服務(wù)。本文所介紹在線電話簿、實時天氣預(yù)報功能,就是對VoIP終端產(chǎn)品功能擴展的一次積極嘗試。
圖1 HTTP客戶端分層設(shè)計框圖
首先,該功能模塊是基于ARM-LINUX嵌入式平臺開發(fā)的,在系統(tǒng)中處于中心地位的是一個獨立的VoIP進程,它包含了VoIP終端主要的功能實現(xiàn)。
HTTP客戶端模塊包含:HTTP客戶端應(yīng)用接口層,它可以被VoIP進程中各線程共享調(diào)用;HTTP客戶端線程,它可以滿足VoIP進程中,其他線程實時并發(fā)地訪問遠端HTTP服務(wù)器的需要;客戶端API的語法編解碼模塊,它服務(wù)于HTTP客戶端API,使其能夠?qū)TTP報文、XML/XHTML數(shù)據(jù)等進行高效的解析與構(gòu)建。HTTP客戶端的功能設(shè)計框圖,如圖1所示:
圖1中,MMI(Man-Machine Interface)線程主要負責用戶與VoIP終端的人機交互任務(wù)。通過MMI線程,用戶訪問遠端服務(wù)器數(shù)據(jù)的場景有兩種:一種是手動訪問的方式;另一種是自動訪問的方式。對于手動方式,MMI線程可以直接調(diào)用HTTP客戶端API函數(shù)進行訪問;但這種方式存在如何有效縮短手動訪問時延的問題。另外一種自動訪問的方式,是通過獨立的HTTP客戶端線程來實現(xiàn)的;該方式面臨著另一個問題:如何實現(xiàn)MMI線程與HTTP客戶端線程之間的數(shù)據(jù)同步問題。上述兩個問題的具體分析與解決,均將在第三節(jié)中進行闡述。每次對遠端服務(wù)器數(shù)據(jù)的訪問,無論以手動方式還是自動方式,均遵循相同的基本流程,如圖2所示:
圖2 通過HTTP客戶端API訪問遠端服務(wù)器流程圖
上層模塊(MMI線程或HTTP客戶端線程等)傳遞相關(guān)的參數(shù)給HTTP客戶端API層;
API層調(diào)用相應(yīng)的報文編碼函數(shù)根據(jù)上層傳遞的參數(shù)構(gòu)建出請求報文;
調(diào)用Linux套接字API建立與遠端HTTP服務(wù)器的TCP連接;
一旦連接建立成功,發(fā)送請求報文,同時等待接收響應(yīng)報文;
當成功接收到響應(yīng)報文,HTTP客戶端API層將調(diào)用相應(yīng)的報文解析函數(shù)對報文進行解析;
將解析得到的數(shù)據(jù)返回給上層模塊,并關(guān)閉TCP連接。
如果連接建立失敗、響應(yīng)超時或失敗,同樣要將錯誤的結(jié)果返回給上層。
圖2描述了HTTP客戶端API層訪問遠端服務(wù)器的過程。調(diào)用socket()創(chuàng)建一個socket文件描述符,其內(nèi)核屬性默認為阻塞模式。當建立連接或接收響應(yīng)數(shù)據(jù)時,如果直接調(diào)用connect()或recv()對創(chuàng)建的socket描述符進行操作,調(diào)用結(jié)果返回之前,當前線程會被掛起,該調(diào)用方式成為“阻塞調(diào)用”。在“阻塞調(diào)用”模式下,如果遠端服務(wù)器不存在或服務(wù)器端不返回數(shù)據(jù),connect()/recv()函數(shù)就會長時間無法返回,進行該調(diào)用的線程將被長時間掛起,而這對于用戶而言顯然是無法接受的。如何解決該問題?
Unix/Linux中,系統(tǒng)調(diào)用select()經(jīng)常在阻塞調(diào)用的非阻塞化場合被用到。其函數(shù)聲明如下:
select()函數(shù)提供了一個fd_set的數(shù)據(jù)結(jié)構(gòu),它是一個長整型的數(shù)組,每一個數(shù)組元素都能與一個打開的文件描述符(如socket描述符)相關(guān)聯(lián)。當調(diào)用select()時,由內(nèi)核根據(jù)I/O狀態(tài)修改fd_set的內(nèi)容,由此來通知執(zhí)行了select()的進程哪一個socket或文件可讀寫。同時select()還提供了一個timeval結(jié)構(gòu),在調(diào)用時,如果超過了timeval參數(shù)所指定的時間長度仍然沒有文件描述符滿足條件,select()就會直接返回。通過timeval參數(shù)可以定制符合用戶要求的最大等待時間(建立連接、接收響應(yīng)數(shù)據(jù)等)。
非阻塞連接建立過程如下:
A. 建立socket,將socket文件描述符設(shè)為非阻塞模式;
B. 調(diào)用connect()函數(shù),建立與socket綁定的連接(該調(diào)
用會立刻返回);
C. 調(diào)用select()檢查socket是否可讀寫;
D. 根據(jù)select()返回值判斷connect()的結(jié)果:成功、超時或失?。?/p>
E. 將socket重新設(shè)置為阻塞模式。
區(qū)別于非阻塞連接過程,由于網(wǎng)絡(luò)數(shù)據(jù)傳輸本身的時延效應(yīng),需要在不改變socket描述符阻塞屬性的情況下,通過動態(tài)輪詢的方式來實現(xiàn)非阻塞的數(shù)據(jù)接收過程,如圖3所示:
圖3 非阻塞數(shù)據(jù)接收過程
N表示最大輪詢次數(shù),以SELECT_T 代表Select()調(diào)用的超時時間,則整個數(shù)據(jù)接收過程的時間延遲最大為
實際測試表明,通過select()函數(shù)實現(xiàn)的非阻塞網(wǎng)絡(luò)通信機制,可以實現(xiàn)通信過程中實時性和可靠性的有效平衡。
VoIP進程的每個線程均是基于一種消息或事件驅(qū)動的自循環(huán)模型設(shè)計的。
這種由消息或事件驅(qū)動的自循環(huán)線程模型,如圖4所示:
圖4 消息/事件驅(qū)動的自循環(huán)線程模型
在每次循環(huán)過程中,線程檢查是否有新的消息傳入或事件發(fā)生;若發(fā)現(xiàn)新的消息或事件,則進行相應(yīng)的處理,完成后進入下次循環(huán)過程,若當前沒有新的消息或事件,則繼續(xù)等待消息/事件的到來,直到定時器超時進入下次循環(huán)。
HTTP客戶端線程的特殊之處在于,它一直等待請求消息而不會超時,一旦受到請求消息就立即處理,并返回響應(yīng)消息給外部請求發(fā)送者,然后進入下一個等待周期。
當MMI線程需要自動訪問遠端服務(wù)器時,直接向HTTP客戶端消息隊列發(fā)送一個請求;處于“等待”狀態(tài)的HTTP客戶端線程收到MMI線程的請求消息,會立即提取消息中的服務(wù)器地址和HTTP請求相關(guān)的參數(shù),然后按照圖2所示的流程通過HTTP客戶端API層與遠端服務(wù)器進行交互;當收到HTTP客戶端API層的返回數(shù)據(jù)時,HTTP客戶端線程就會將這些數(shù)據(jù)以一定的組織形式,發(fā)送到MMI線程的消息隊列,然后重新進入侍候狀態(tài);當MMI線程收到來自HTTP客戶端線程的消息時,該自動訪問過程結(jié)束。
3.1.1 手動搜索功能
該功能通過MMI線程直接調(diào)用HTTP客戶端API實現(xiàn),基本流程為:用戶輸入搜索條件;MMI線程調(diào)用HTTP客戶端API向遠端服務(wù)器發(fā)送HTTP搜索請求;如果搜索返回成功,則將搜索結(jié)果提供給用戶查看,否則,提示用戶錯誤信息。
3.1.2 自動查詢功能
該功能通過圖5所示的MMI與HTTP客戶端線程的同步機制實現(xiàn),基本流程,如圖5所示:
在線天氣預(yù)報屬于MMI線程中的常駐功能,一旦MMI線程啟動,就會直接觸發(fā)它的運行.
檢查在線天氣功能是否開啟,如未開啟,則重置計時器,等待其超時再次檢測功能是否開啟,否則進入下一步;
向HTTP客戶端線程發(fā)送信息查詢請求;如客戶端線程成功返回響應(yīng)消息,則進入下一步,否則重新進行上一步;
將HTTP客戶端線程返回的天氣信息顯示在LCD屏上;
重置定時器;
等待定時器超時,返回第一步再次更新天氣信息。
本文針對當前VoIP終端特色功能擴展的需要,設(shè)計了一種輕型、高效的HTTP客戶端,并對該客戶端的設(shè)計架構(gòu)和實現(xiàn)中遇到的關(guān)鍵問題進行了闡述。由于采用了相對開放的架構(gòu)設(shè)計,實現(xiàn)了相互獨立的HTTP客戶端接口層、HTTP客戶端線程以及語法編解碼模塊,因此,除了已實現(xiàn)的在線號碼簿和在線天氣信息外,還可以基于該客戶端,進行其他類似的功能擴展。實際測試表明,該客戶端具有實時性高、穩(wěn)定性強、系統(tǒng)資源開銷少等特點,達到了預(yù)期的設(shè)計指標。
[1]Wikipedia: Voice over IP[G/OL], http://en.wikipedia.org/wiki/Voice_over_IP, 2011.
[2]Neil Matthew, Richard Stones. Beginning Linux Progrmaming 4th Edition[M]. 北京,人民郵電出版社 ,2010.
[3]宋敬彬, 孫海濱. Linux網(wǎng)絡(luò)編程,[M]北京,清華大學出版社, 2010.
[4]謝希仁. 計算機網(wǎng)絡(luò)(第5版)[M].北京電子工業(yè)出版社,2008.
[5]許信順. 嵌入式 Linux應(yīng)用編程[M], 北京,機械工業(yè)出版社, 2007.
[6]Internet Engineering Task Force, Hypertext Transfer Protocol - HTTP/1.1[S], http://tools.ietf.org/html/rfc2616,1999.