1. 程式人生 > >物聯網網路程式設計和web程式設計

物聯網網路程式設計和web程式設計

本文是基於嵌入式物聯網研發工程師的視覺對網路程式設計和web程式設計進行闡述。對於專注J2EE後端服務開發的同學來說,這篇文章可能稍微簡單。但是網路程式設計和web程式設計對於絕大部分嵌入式物聯網工程師來說是一塊真空鄰域。

的確,物聯網研發應該以團隊協作分工的方式進行,所以有嵌入式裝置端、閘道器、web前端、APP、後端開發等專屬崗位。作為系統架構師,自然需要掌握各種崗位的關鍵技術。作為嵌入式工程師,掌握網路程式設計、web程式設計,能極大地擴充套件自己的視野和構架思維,能夠主動地對系統的各種協議和應用場景提出優化的見解,而不僅僅是接受任務攤派,至少,能夠在不需要依賴後端工程師的情況,能夠快速搭建一個物聯網demo系統。因此,掌握一些基本的網路程式設計、web程式設計技能,對於提升物聯網研發工程師的開發能力是非常重要的。

一、OSI七層模型和TCP/IP四層模型

OSI七層模型是網路協議的理論研究模型,或者可以稱之為理想的模型,而TCP/IP四層模型才是事實標準,是已經被廣泛使用的模型。兩者之間的關聯圖如下:


衡量一個物聯網平臺或者協議是否實用的關鍵技術的因素是它提供的訊息觸達能力,直接影響物聯網應用開發。所以,我們從訊息觸達能力去分析TCP/IP這個事實標準模型。我們設想以下場景,並分析。

         

1.網路介面層。路由器1和wifi音箱、空調、熱水器組成一個家庭區域網,其使用wifi(802.11)協議進行通訊。該協議定義了物理訊號、資料幀格式、丟包重發機制、流量控制等等。這些都是網路介面層的任務。還有,多個裝置共享通道,同時發資料會產生衝突,它是怎麼解決的,這也是網路介面層的內容。其實,物聯網工程師不必在意這些內容。因為wifi物理訊號方面的內容是由wifi晶片廠商負責,而wifi單晶片(wifi+SOC)則會提供SDK包並提供SOCKET程式設計介面了。所以,我們職責的重點是關注網路層以上的程式設計開發知識。

2.網路層,即IP協議,最基礎的認識是每個IP對應一個物聯裝置、手機或者一個後方伺服器。原則上一個網絡卡對應一個IP,如圖中wifi音箱、wifi熱水器均有一個獨立的IP。網路之間的通訊都是基於IP進行的,網路包會通過路由器最終送到目標IP所對應的裝置上。

Wifi音箱等家庭裝置加入家庭區域網,其實是各獲得一個區域網IP,192.168.*.*,包括路由器1也有一個區域網地址,但是路由器1還有一個網際網路IP。只有路由器的網際網路IP才能被外界所獲知,外界是不能主動獲知區域網IP具體對應哪個裝置的,只有路由器1才知道,因此所有對外發送的資料包的源IP都是路由器1的網際網路IP,外界傳送給裝置的資料包的目標IP也是路由器的網際網路IP。

我們都知道,裝置上線時需要向物聯平臺伺服器告知自己的狀態,以便於使用者控制。因此物聯平臺伺服器的IP必須是一個網際網路IP,或者是一個域名(DNS協議可以將域名解析為IP)。如果它是一個區域網IP,那裝置是不可能訪問到的。

這裡,我們還必須要記住一點,裝置和物聯平臺的第一次通訊永遠都應該裝置主動發出,因為就算物聯平臺知道路由器1的公網IP,它也無法將訊息傳送到內部的裝置的。另外,伺服器必須要持續裝置到達物聯平臺最後一跳的路由資訊,因為路由資訊原路返回的過程中具有路由器1記錄是哪個裝置發出的資訊。如果不記錄這個資訊,物聯平臺單靠路由器1的網際網路IP是無法觸達到具體裝置的。

如果你不能理解上面這一段話,就記住,物聯平臺通過路由器1的網際網路IP主動發一條訊息到裝置是不能成功的,但是,當裝置發一條訊息給物聯平臺後,物聯平臺直接響應該資料包(IP源地址和目標地址調換位置)是可以觸達裝置的。如果是滿足一問一答的方式,那麼伺服器不需要記錄這個路由資訊,如果需要滿足伺服器主動發訊息給裝置的場景,那麼伺服器是需要記錄這個資訊的。

另外,我們知道,網路裝置在物理上表現為一個真實的網絡卡,網絡卡的MAC地址是6個位元組,48位。在一個區域網內通訊,網路程式設計時都是基於IP地址的,路由器或者交換機如何通過IP地址找到對應的MAC地址,即為ARP地址解析協議,這個也是網路層的職責,但是作為開發人員來說,我們瞭解即可。

3. 傳輸層,即TCP/UDP協議。對於傳輸層,我們需要理解的是,一臺PC或者手機上執行的網路運用可能很多,但是他們都對應同樣一個IP。作業系統如何將一個數據包分發給對應的網路運用呢?這就依靠傳輸層所定義的埠來區分。常見的網路應用層協議都會預設傳輸層埠號,如FTP對應21,HTTP對應80,SMTP對應25等等。傳輸層除了定義埠號之外,還有兩個非常重要的協議,即TCP面向連線的協議和UDP資料包協議。前者可以理解為一個虛擬的電話連線協議,一旦雙方打電話建立起連線後雙方通話的過程中,所有的資料包均是走同樣的路由路徑。因為面向連線的協議會在頻寬中預留資源來保障,所以面向連線協議能夠保證質量,因此適用於一些對資料質量要求嚴格的網路運用中,如電子郵件應用,如果不保證質量,郵件內容都不保證正確,誰會使用這個郵件系統呢?但是,對於一些音訊視訊類運用,丟一兩幀完全不影響使用者體驗,則會使用UDP協議,其不是面向連線,發完後之前的路由資訊可以不在儲存,其是使用最大努力交付(即trymy best)。

4. 應用層。常見的網路應用協議包括HTTP、FTP、SMTP、POP等等。嵌入式物聯應用是建立在這些網路應用協議的基礎之上的。這些協議會規範基本的請求連線、響應和資料傳輸等方面的格式。作為嵌入式物聯網應用來說,其應該自行定義應用協議的格式,這些資料格式可以簡單自定義,也可以使用成熟的標準格式,如HTML、XML、JSON等等。由於防火牆一般只放開埠為80的HTTP資料包,所以物聯網應用一般都會構建在HTTP的基礎上。

所以,我們要區分網路應用層協議HTTP和應用自定義協議。後者使用前者進行傳輸通訊。不管應用自定義協議使用哪一種格式,都需要通訊雙方同時使用。物聯裝置和物聯平臺後臺通訊時,可以使用簡單的XML格式或者JSON格式,而物聯平臺還要被PC瀏覽器訪問,那麼,由於瀏覽器只支援HTML格式,則要求物聯平臺後臺提供HTML格式的內容服務,同理,物聯網平臺和手機APP之間的通訊可以用XML或者JSON。甚至,我們可以自定義簡單的命令來實現功能,但是使用XML或者JSON這些格式有助於資料有良好的可讀性,而且也有成熟的類庫來解釋。

這些都是建立在HTTP網路應用協議的基礎上的。


二、socket程式設計

socket程式設計分為TCP和UDP兩種方式。分別如下:


可見,TCP/UDP的socket套接字在通訊之前需要繫結(bind)IP和埠地址。對於TCP來說,伺服器需要先偵聽listen,而客戶端發起connect請求後,伺服器才能accept,之後即建立面向連線的通訊環境,通過send/recv函式進行通訊。

而UDP程式設計則很簡單,繫結之後可以立即開始資料傳輸。

除了掌握基本的socket程式設計之外,還需要清楚以下知識:

1)阻塞和非阻塞。網路套接字有阻塞和非阻塞之分。如假設建立的socket是阻塞的,那麼其recv函式就一定要等到對方傳送資料過來,才會返回,否則會一直處於阻塞狀態。而非阻塞狀態則是立即看看緩衝有沒有資料,如果有就返回資料,沒有會返回錯誤,而不是一直死等。阻塞模式可以簡單地理解為同步工作模式,而非阻塞模式可以理解為非同步工作模式。

2)多路複用。作為伺服器,可能會存在多個客戶端連線,如果輪詢每個客戶端socket有沒有資料,那效率多累啊。Socket程式設計的select和poll介面用來解決這類多路IO複用的問題,它能夠同時偵測多個連線的資料通訊。


三、B/S和C/S

1.B/S是瀏覽器和客戶端模式,使用HTML語法格式。其使用一問一答,即伺服器是無狀態的,它不知道客戶端之前是否已經訪問過。無狀態有助於伺服器高效率而且穩定地服務。但是這種模式對於物聯網應用的影響是致命的。因為伺服器無法主動地傳送訊息給物聯裝置。那麼,如何改進呢?

1)ajax技術。Ajax技術最新是為了解決頁面區域性重新整理頻繁的效率問題的。即一個HTML頁面的區域性資料傳送變化了,在ajax之前需要重新發送一次請求,來重新整理整個頁面。而ajax則是僅僅向伺服器請求傳送變化的資料。前者在請求時會看到頁面有閃爍,而後者則沒有。我們正好可以利用ajax來定時向伺服器發起請求,詢問伺服器是否有更新的資料。如果詢問頻率高,那麼實時效果就好,但是會加重伺服器負擔。本質上,還是一問一答的形式,而不是雙向通訊。Ajax需要瀏覽器技術支援。

2)websocket技術。Websocket是為了解決HTML的雙向通訊問題而提出的,其在第一條HTTP請求之後會讓伺服器將後續的協議更新到Websocket進行通訊。Websocket需要tomcat7.0以上的執行容器技術支援。

物聯網應用開發在裝置端可以通過socket程式設計來模擬HTTP協議,同樣可以模擬HTTP之上的HTML、XML或者Websocket。

2. C/S

C/S客戶端和伺服器程式設計在智慧機出現之前在PC桌面領域一度被認為會在逐漸被B/S所取代,但是在智慧機裝置端它又煥發新生。儘管HTML5發展迅速,但是個人覺得瀏覽器在手機等智慧裝置端的體驗還是比不上原生APP。而HTML5更大的優勢是其移植性很強。

C/S程式設計可以直接使用socket通訊進行通訊,那自然不存在雙方通訊的問題。如果C/S程式設計使用http類庫進行程式設計通訊,它同樣也會存在雙向通訊的問題。

目前看來,很多人都希望沿用J2EE那套業務架構來支援物聯網,但是物聯裝置畢竟是資源有限,有些終端可能是簡單的微控制器,其跑完整的TCP/UDP協議都比較困難,因此有人提出了精簡版的TCP/IP協議,如CoAP(受限制的應用協議(ConstrainedApplicationProtocol)的代名詞)、ucIP、LWIP等等。從業務應用協議來看,IBM研發的MQTT可能會成為物聯網應用協議的標準。

四、 Web程式設計

Web程式設計最先指的是瀏覽器展示內容的語法程式設計。Web靜態語言即是HTML。

1.HTML不支援資料的動態變化。因此產生了基於解釋引擎的動態語言,如ASP、PHP、JSP等等。這類語言會使用HTML/CSS來描述展現樣式,而使用動態語言來控制資料的展現,例如訪問資料庫獲取新資料等等。

需要知道,ASP,PHP,JSP這些語言是伺服器程式語言,當用戶通過瀏覽器訪問伺服器對應網頁時,該網頁的ASP/PHP/JSP等內容會經過伺服器的解釋引擎轉化為具體的資料,最終和其他的HTML、CSS資料一起返回給瀏覽器進行展現。因此,瀏覽器得到的永遠都是確定的HTML、CSS和資料,不存在ASP/PHP/JSP的語句。

2.javascript指令碼。指令碼是瀏覽器技術支援的語法,而不是伺服器技術支援的。例如一個登入介面,要確保使用者輸入的正確性,如不規則字元,長度太長等等,一般會使用javascript指令碼進行檢測,而不需要傳送請求給伺服器。上述講到的ajax技術也是瀏覽器支援的指令碼技術。

3.jQuery,它是對javascript技術的封裝,能夠更好地進行前端程式設計控制。

4.HTML/CSS/JS指令碼,稱為web前端程式設計開發,而ASP/JSP/PHP等為後端開發。

5.後端開發自然會涉及到資料庫訪問、業務邏輯,並且其需要和前端進行互動。因此,web應用程式設計架構普遍使用MVC程式設計模型,即M為資料模型,負責資料庫訪問;V為檢視,負責展現;C為控制。MVC模型能夠對展現和資料庫進行良好的分離,有助於應用開發。

6.作為整體執行架構來理解,伺服器需要包括資料庫(如mysql)、web應用和解釋引擎和web服務(如apache和tomcat)。Apache提供http服務。

7.JSP的基礎是JAVA語法,J2EE架構提供servlet技術,用於支援網路運用。JSP其實是對servlet的高階封裝並作為獨立的技術出現的,JSP側重支援B/S方面的網路運用,而servlet則通過對映類的方式支援C/S方式的網路運用,如微信藍芽接入和wifi接入的後端技術即使用servlet進行支援, 頂層使用XML/JSON格式。