彭鳳凌,庹先國,2,王洪輝,蒲建華
(1.成都理工大學(xué) 地質(zhì)災(zāi)害防治與地質(zhì)環(huán)境保護國家重點實驗室,四川 成都610059;2.西南科技大學(xué) 核廢物與環(huán)境安全國防重點學(xué)科實驗室,四川 綿陽621010)
NAT技術(shù)[1-3]的發(fā)展雖然緩解了IP地址枯竭問題,但卻使得公網(wǎng)不能主動訪問內(nèi)網(wǎng),位于兩個不同NAT設(shè)備后的客戶端通信問題更是麻煩,給通信帶來了極大不便。而不同內(nèi)網(wǎng)之間通信的應(yīng)用在當(dāng)今信息時代無處不在,如在移動電子商務(wù)方面[4],甚至將移動終端納入互聯(lián)網(wǎng)上一個普通網(wǎng)絡(luò)節(jié)點,并與其它平臺通信和進行各種事務(wù)的處理,因此怎樣突破NAT設(shè)備實現(xiàn)不同內(nèi)網(wǎng)的通信顯得十分重要。對此,前人有許多研究,如文獻 [5]介紹了一種UDP協(xié)議通過打洞實現(xiàn)與內(nèi)網(wǎng)通信的方法[5],該通信方案比較完善,但UDP協(xié)議建立的端口映射不能持久,也就不能夠保證打洞的可靠性和穩(wěn)定性,且UDP本身不可靠,當(dāng)需要實現(xiàn)大數(shù)據(jù) (如文件)傳輸時,需要改進協(xié)議解決數(shù)據(jù)掉包等問題,使得通信過程復(fù)雜,信息傳遞的實時性差。文獻 [6]提出了一種TCP協(xié)議的P2P通信方法[6],雖能保證通信的可靠性,但是通信方案會因NAT設(shè)備類型的不同而有所變化,且對于屬于 “對稱型”的NAT設(shè)備,文獻[5-6]所提出的方法往往不能夠真正穿透內(nèi)網(wǎng)。基于以上問題,筆者通過對Android系統(tǒng)平臺手機的無線通信技術(shù)進行研究,在摒棄 “打洞”思路基礎(chǔ)上采用 “轉(zhuǎn)發(fā)”思路,設(shè)計并實現(xiàn)了基于Android手機與內(nèi)網(wǎng)PC的通信系統(tǒng)。在確保通信安全性基礎(chǔ)上能突破所有NAT設(shè)備 (包括最難實現(xiàn)打洞的 “對稱式”NAT設(shè)備)。此外,該系統(tǒng)在實現(xiàn)信息傳輸和遠程控制功能上提供了擴展接口便于二次開發(fā)并用在不同通信場合,具有一定借鑒價值。
Android應(yīng)用程序一般由活動、服務(wù)、廣播接收者和內(nèi)容提供者四部分組成[7-10],活動用于界面顯示和各種功能的實現(xiàn),服務(wù)是運行于后臺無界面的程序,廣播接收者提供系統(tǒng)內(nèi)的所有廣播實現(xiàn),內(nèi)容提供者則為其他程序提供數(shù)據(jù)讀取和存儲。而本文中,Android應(yīng)用程序主要由活動完成,下面對用到的重要API做介紹:①socket類 (主要完成Socket網(wǎng)絡(luò)通信),它的getOutputStream方法可以獲取輸出流用于發(fā)送信息,getInputStream方法用于讀取信息到指定緩沖區(qū),close方法用于關(guān)閉套接字結(jié)束通信。②OutputStream類、,OutputStreamWriter類和BufferedWriter類 (完成將數(shù)據(jù)寫入到輸出流),主要運用write方法寫入數(shù)據(jù),使用flush方法發(fā)送數(shù)據(jù)。InputStream類 (完成將數(shù)據(jù)從指定區(qū)域讀出),主要用read方法讀取數(shù)據(jù)。
公網(wǎng)指國際互聯(lián)網(wǎng),而內(nèi)網(wǎng)指局域網(wǎng)。通常內(nèi)網(wǎng)都是位于NAT設(shè)備后,因此只要能夠突破NAT設(shè)備,就能實現(xiàn)與內(nèi)網(wǎng)的通信。由于網(wǎng)絡(luò)安全性及NAT技術(shù)的出現(xiàn)等問題,公網(wǎng)與內(nèi)網(wǎng)的通信必須遵循一些規(guī)則。對于一臺具有公網(wǎng)IP的計算機來說,它是放在Internet上且具有全球唯一性,其它任何計算機都可以主動與它通信,但對于一個只具有內(nèi)網(wǎng)IP的計算機而言,由于它的IP在Internet上是不被認可的,因此它只能被位于同樣內(nèi)網(wǎng)的計算機主動訪問到,不能被位于公網(wǎng)或其它內(nèi)網(wǎng)的計算機主動訪問到。根據(jù)此規(guī)則,由于Android手機聯(lián)移動網(wǎng)后都是處于內(nèi)網(wǎng)的,因此不能直接與處于其它內(nèi)網(wǎng)的計算機通信。
Socket指套接字,它是實現(xiàn)兩個應(yīng)用程序之間通信的一種技術(shù),通信雙發(fā)只需創(chuàng)建各自的Socket并將IP地址和端口等信息封裝到Socket里,就可以直接通過操作Socket來完成信息的傳輸。采用此技術(shù)一般有兩種通信方式,即TCP和UDP。由于TCP通信方式比UDP更加可靠,加之本文設(shè)計的通信系統(tǒng)也涉及到文件傳輸,對通信可靠性要求比較高,因此本文采用TCP方式完成信息的傳輸。
如圖1所示,根據(jù)公網(wǎng)與內(nèi)網(wǎng)通信規(guī)則和Socket通信原理,由于內(nèi)網(wǎng)PC和Android手機都可以主動向公網(wǎng)PC發(fā)出連接請求并與公網(wǎng)PC通信,因此Android手機可以通過公網(wǎng)PC將信息轉(zhuǎn)發(fā)到內(nèi)網(wǎng)PC從而實現(xiàn)手機與內(nèi)網(wǎng)PC的通信。為闡述方便,下面將Android手機端稱A方,將公網(wǎng)PC稱S方,將內(nèi)網(wǎng)PC稱B方。首先A和B都通過創(chuàng)建Socket向S發(fā)出連接請求,S通過創(chuàng)建兩個不同的Socket分別接受來自A和B的連接請求,這樣,A和S之間可以相互通信 (稱第一階段),B和S之間也可以相互通信(稱第二階段)。接下來A先將信息封裝并發(fā)送到S,S收到信息后將其拆封,取出相關(guān)信息后,將信息再次封裝并向B發(fā)送信息。B收到信息后將其拆封,取出需要信息然后交由信息處理機制進行下一步的處理。整個過程涉及兩次信息封裝和信息拆封。對于A方采用Eclipse并用Java語言建立Android應(yīng)用程序開發(fā),對于S方和B方采用Visual C++并用C語言建立Win32應(yīng)用程序開發(fā),圖2為通信方案設(shè)計圖。
整個通信過程較復(fù)雜,如圖3所示,對于A方,為避免阻塞主線程,會開啟一個線程用于信息的傳輸,當(dāng)創(chuàng)建完Socket并將IP地址和端口號綁定后即可向S發(fā)出連接請求,請求一旦被S接受,A會根據(jù)之前用戶對界面的不同操作發(fā)送不同的數(shù)據(jù)包 (數(shù)據(jù)包1、數(shù)據(jù)包2和數(shù)據(jù)包3任選其一)。數(shù)據(jù)包1實現(xiàn)簡單的文本信息傳輸,它包含標識信息和字符串信息,數(shù)據(jù)包2實現(xiàn)簡單命令傳輸,它包含標識信息和命令編號信息,數(shù)據(jù)包3實現(xiàn)文件傳輸,它包含標識信息和文件名稱。若選擇發(fā)送的數(shù)據(jù)包是數(shù)據(jù)包1或數(shù)據(jù)包2,A方就基本完成了本次通信任務(wù),若選擇的是數(shù)據(jù)包3,A方還需反復(fù)讀取文件并將文件二進制流方式分多次發(fā)送到S方從而完成文件的傳輸。對于S方,當(dāng)程序啟動后,為了實現(xiàn)接收與發(fā)送同時進行,會開啟兩個線程(線程1和線程2)創(chuàng)建兩個套接字 (SocketA和ScoketB),然后監(jiān)聽端口等待連接請求的到來。線程1用于接收信息,當(dāng)接受連接后,會接收來自A的信息并將信息進行拆封,根據(jù)拆封后得出的不同標識信息會進行不同的操作,若標識信息是 “1”,則將拆封出的字符串保存并重新封裝數(shù)據(jù)包1。當(dāng)標識信息是 “2”時,則將拆出的命令編號保存并重新封裝數(shù)據(jù)包2,當(dāng)標識信息是 “3”時,會首先創(chuàng)建一個空的臨時tmp文件,然后向A發(fā)送反饋信息表示已經(jīng)準備好接收文件,然后將每次接收到的二進制流寫入文件,最后將數(shù)據(jù)包3中拆出的文件名保存并重新封裝數(shù)據(jù)包3。S方無論收到哪個數(shù)據(jù)包,接收完畢后都會將X置1以啟動S的信息發(fā)送模塊。線程2用于發(fā)送信息,當(dāng)接受B的連接請求后,會判斷標識X是否為1,當(dāng)條件成立,表示S已經(jīng)將A發(fā)的信息接收完畢,此時會先將X置0,并根據(jù)線程1收到的標識信息決定將要發(fā)送給B的數(shù)據(jù)包,當(dāng)數(shù)據(jù)包發(fā)送完成后,S要做的工作與A之前要做的工作類似,因此不再說明。對于B,當(dāng)收到S發(fā)的信息后,所做的工作與S接收A發(fā)的信息類似,因此也不再說明,當(dāng)信息接收完成后,B會進入信息處理機制,收到文本信息會直接顯示在文本框中,收到的是命令編號則執(zhí)行相關(guān)操作,收到的文件會直接保存到硬盤。
圖3 通信流程
數(shù)據(jù)包封裝結(jié)構(gòu)見表1。
表1 數(shù)據(jù)包封裝結(jié)構(gòu)
在整個通信過程中涉及到多種類型信息的收發(fā),如果每次的通信只實現(xiàn)一種信息的傳輸,不僅通信效率低且通信協(xié)議異常復(fù)雜,因此需要一種方式將多種類型信息進行封裝并一次性發(fā)送,以便接收方能夠拆封信息提取各種數(shù)據(jù)。但由于TCP通信方式是基于服務(wù)流的,無邊緣性保證,即每次發(fā)送信息只是將信息放入發(fā)送的緩沖區(qū),接收方只是從接收緩沖區(qū)中提取出信息,至于信息何時發(fā)送,何時收到,都是不可控的,并且發(fā)送信息的次數(shù)不等于接收信息的次數(shù),因此必須設(shè)計信息的封裝與拆封方法,這里本文采用結(jié)構(gòu)體的方式進行信息的封裝與拆封,對于S方和B方由于采用C語言開發(fā),可直接定義結(jié)構(gòu)體,S方用定義的結(jié)構(gòu)體直接接收A方發(fā)送的信息,之后進行相關(guān)處理并用新的結(jié)構(gòu)體封裝提取出的信息并發(fā)送此結(jié)構(gòu)體給B方,B方也可直接用結(jié)構(gòu)體方式接收信息,并調(diào)用結(jié)構(gòu)體的成員變量提取各種數(shù)據(jù)進行相關(guān)處理。但對于A方,由于Java語言沒有結(jié)構(gòu)體這種數(shù)據(jù)類型,所以必須模擬結(jié)構(gòu)體的存儲特點,先將各種類型的數(shù)據(jù)進行相關(guān)轉(zhuǎn)換,然后利用System.arraycopy方法將各種類型的數(shù)據(jù)按正確的順序?qū)懭氲捷敵隽髦腥ィ詈笾恍璨捎胒lush方法發(fā)送輸出流的數(shù)據(jù)即可,下面是整型數(shù)據(jù)的轉(zhuǎn)換方法和寫入數(shù)據(jù)到輸出流方法的相關(guān)代碼。
由于采用TCP方式傳輸文件,因此不必擔(dān)心掉包和數(shù)據(jù)包亂序等問題,對于發(fā)送方來說,只需每次將文件的部分二進制讀出并立即發(fā)送,之后重復(fù)此動作直到文件讀完。對于接收方來說,只需每次將收到的二進制流寫入空文件并繼續(xù)接收信息,當(dāng)收不到信息表示文件傳輸完畢。這里為了屏蔽文件類型,S在接收到文件二進制流后,將其寫入tmp緩存文件中,并將A發(fā)送的文件名 (包括后綴名)一起封裝到數(shù)據(jù)包3中并發(fā)送給B,B在收到信息后首先利用收到的文件名創(chuàng)建空文件 (這樣就保證了A發(fā)送的文件類型與B創(chuàng)建的空文件類型一致),然后將收到的二進制流寫入空文件。當(dāng)所有二進制數(shù)據(jù)寫入完成,文件即傳輸完成。
信息處理機制位于B方,如圖4所示,當(dāng)B收到數(shù)據(jù)包后,先拆開標識信息進行判斷,標識為1,則獲取文本并將其顯示在文本框。標識為2,則獲取編號并執(zhí)行相應(yīng)的操作 (圖中列舉了6種編號所對應(yīng)的操作,開發(fā)者可自行添加編號并增加相應(yīng)操作從而對該系統(tǒng)的遠程控制功能進行擴展和二次開發(fā))。標識為3,則接收文件并保存到指定目錄。
圖4 信息處理流程
第一:打開Android端、公網(wǎng)PC端和內(nèi)網(wǎng)PC端的應(yīng)用軟件。第二:在內(nèi)網(wǎng)PC軟件上的點擊 “建立連接”按鈕。第三:在Android手機端文本編輯右邊的框中輸入文字 (如 “我是張三”),點擊 “開始發(fā)送”按鈕,當(dāng)內(nèi)網(wǎng)PC端收到同樣字樣時,表示本次通信已經(jīng)突破了NAT設(shè)備。第四:在Android端命令編輯右邊的框中輸入命令編號(如003)點擊 “開始發(fā)送”按鈕,PC端會執(zhí)行相應(yīng)的操作。第五:在Android端點擊 “文件瀏覽”按鈕,選擇要發(fā)送的文件,點擊 “開始發(fā)送”按鈕,PC端會顯示收到文件的文件名,并將文件保存到指定目錄。圖5和圖6為手機端和PC端測試效果圖。
用軟件通過大量測試,該系統(tǒng)不僅能夠高效實時的實現(xiàn)手機與內(nèi)網(wǎng)PC的通信 (包括文件的傳輸),且能夠?qū)崿F(xiàn)對PC的遠程控制功能,通信系統(tǒng)良好。
本文首先通過對Android通信相關(guān)API進行了分析,在遵循公網(wǎng)與內(nèi)網(wǎng)通信規(guī)則和Socket通信原理基礎(chǔ)上,利用第三方服務(wù)器轉(zhuǎn)發(fā)信息這一思路,設(shè)計并實現(xiàn)了Android手機與內(nèi)網(wǎng)PC的通信系統(tǒng),最后通過實驗驗證了該系統(tǒng)的可靠性。針對該系統(tǒng)的 “信息轉(zhuǎn)發(fā)”機制,本文設(shè)計了嚴謹?shù)耐ㄐ艆f(xié)議,對網(wǎng)絡(luò)協(xié)議開發(fā)者提供了參考價值。同時該系統(tǒng)很好的實現(xiàn)了移動終端與內(nèi)網(wǎng)PC間的信息傳輸和遠程控制功能,無論是科學(xué)研究還是實際應(yīng)用都有一定借鑒價值。
:
[1]KONG Lingwang.Analysis of NAT technology and application[J].Science & Technology Information,2011,11 (32):26-26 (in Chinese).[孔令旺.NAT技術(shù)及應(yīng)用淺析 [J].科技資訊,2011,11 (32):26-26.]
[2]REN Wen.Analysis of NAT technology and its implementation[J].Journal of Gansu Radio & TV University,2011,21(2):81-83 (in Chinese).[任文.淺談 NAT技術(shù)及其實現(xiàn)方法 [J].甘肅廣播電視大學(xué)學(xué)報,2011,21 (2):81-83.]
[3]ZAI Qinqin,YANG Jing.Research and application of NAT technology [J].Ship Electronic Engineering,2011,11 (7):123-125 (in Chinese).[宰芹芹,楊婧.NAT技術(shù)的研究與應(yīng)用 [J].艦船電子工程,2011,11 (7):123-125.]
[4]WEI Nan,CHEN Ping.Mobile e-commerce technology and application analysis [J].Technology and Market,2012,12(4):92-93 (in Chinese).[魏楠,陳平.移動電子商務(wù)技術(shù)及應(yīng)用分析 [J].技術(shù)與市場,2012,12 (4):92-93.]
[5]WANG Yan,WU Qinglin,CAI Weiping.Study of NAT traversal program of P2Pnetwork communication [J].Journal of Yunyang Teachers College,2012,31 (3):93-95 (in Chinese). [王焱,吳青林,蔡衛(wèi)平.P2P網(wǎng)絡(luò)通信中穿越NAT方案研究 [J].鄖陽師范高等??茖W(xué)校學(xué)報,2012,31(3):93-95.]
[6]ZHANG Weixin,HAN Xiuling.TCP traversal NAT of P2Pcommunication technology [J].Computer Age,2008,8 (11):62-64(in Chinese).[張偉欣,韓秀玲.TCP穿透NAT的P2P通信技術(shù)研究 [J].計算機時代,2008,8 (11):62-64.]
[7]ZHU Guiying.Android development applications from the entry to the master [M].Beijing:Railroad Publishing Press,2011(in Chinese).[朱桂英.Android開發(fā)應(yīng)用從入門到精通[M].北京:中國鐵道出版社,2011.]
[8]JIANG Yunchen.Principles of android system and practical application [M].Beijing:Beijing Institute of Technology Press,2011(in Chinese). [蔣耘晨.Android系統(tǒng)原理和實戰(zhàn)應(yīng)用[M].北京:北京理工大學(xué)出版社,2011.]
[9]YU Zhilong,CHEN Xiaofeng.Getting started and practice of google android development [M].Beijing:Posts&Telecom Press,2009 (in Chinese).[余志龍,陳小風(fēng).Google android開發(fā)入門與實戰(zhàn) [M].北京:人民郵電出版社,2009.]
[10]LE Yan,YAO Shanglang,CHEN Xiaofeng,et al.Google android SDK development examples [M ]. Beijing:Posts&Telecom Press,2009 (in Chinese). [勒巖,姚尚郎,陳小風(fēng),等.Google android SDK開發(fā)范例大全 [M].北京:人民郵電出版社,2009.]