關鍵字:abdroid 模擬器 socketjava
忽然有人說使用android的模擬器作socket服務器,PC作客戶端,使用UDP通訊的時候,android端沒法收到數據包。反過來沒問題,我以爲這怎麼可能,首先若是你代碼沒問題的話,那就只有真實IP和端口有問題了。因而我搜索了一下,網上還真很多人問這個問題,我不得不說如今java程序員都被SSH毀了,不少已經到了不去思考的地步了,遇到問題想都不想一問,原來你也這樣?既然你們都這樣,那就說明沒法解決了……….
特別是對java來講開源庫各類各樣,不少人已經養成了不去思考和嘗試的習慣,直接找現有的實現了。這樣就徹底沒有編程的樂趣了,哎,好了回到本文要點吧。首先對於TCP/UDP通訊來講至少要有必定的知識。
首先在不考慮TCP/UDP的具體協議和實現方式、網絡設備和OSI各類協議的前提下至少要明白java的SOCKET框架,固然SOCKET對於各類語言來講道理是徹底同樣的,只是底層實現不一樣而已,到了java連socket的實現也不須要管了,只要知道類庫怎麼用就能夠。
socket通訊至少須要兩個前提,對方的IP和端口。這也是基要求,因此出問題了在排除代碼問題以後只能是出如今這裏了,固然還有就是你網絡的物理結構沒問題。而後是本文的使用範圍,本文的範圍是PC和android模擬器或者使用USB方式與真實android進行socket通訊。若是android鏈接上路由設備,與PC處於同等地位,對外有獨立IP的狀況下,好比WIFI。天然不在本文討論範圍,這時候你查看兩個設備的IP而後指定端口鏈接就是了。
在此須要另外說明android設備的IP策略問題。當android設備與PC相連的的狀況下,會默認PC的IP爲10.0.2.2,自身的IP爲10.0.2.15/127.0.1。也就是說android設備鏈接IP10.0.2.2就能夠達到鏈接PC的效果,可是反過來,PC沒法知道android的IP地址因此你沒法使用某個默認值來主動向android設備發出鏈接請求。在想到這點時基本就明白接下來要怎麼作了。
首先是TCP狀況下,TCP是有鏈接狀態的,因此任何一段鏈接創建成功就能夠通訊。使用TCP/SOCKET鏈接android設備的場景不少,好比,在android設備中有一個本身的apk作socket服務器,而後再PC端的程序須要與其創建鏈接而後獲取android設備的詳細狀況。這時候通常是用adb forward 將本機 TCP端口轉發到android設備的TCP端口,這樣在PC端就能夠無需知道android設備的IP直接向本機,如127.0.0.1的某個端口發送數據包,以後端口轉發機制會將其轉發到android設備。這個很少說,沒什麼意思。
接下來是UDP,之因此着重說UDP,是由於UDP很是特殊。好在這裏是與PC直連,可是adb forward不能轉發UDP端口信息,只能是TCP…. 好吧,也正由於如此我發現了轉發端口的基本命令redir。
redir add < udp/tcp >:< pc端口 >:< 模擬器端口 >,如redir add udp:1096:1097 redir tcp:1096:1097,做用就是將PC的1096端口轉發到android設備的1097端口,固然兩個端口號能夠相同,由於他們是在兩個不一樣的設備上。可是有個缺點,就是不如adb forward靈活。操做過程以下:

如上圖,PC端使用telnet命令鏈接到android設備,telnet須要的IP就是本機,端口可使用adb devices命令查看,鏈接成功以後可使用redir命令,有list、add、del幾個參數,list如圖就是列出存在的轉發關係,add添加,del就是刪除了,詳細說明參考文檔這裏沒必要多說。設置轉發成功以後就有一個從PC看是1098的通訊端口,從android'設備看是1097通訊端口的直連通道。接下來上代碼。

上圖左側爲android代碼,實現一個UDP/SOCKET的服務端,監聽本地1097端口。右側爲PC端java代碼直接向本機1098端口發送UDP數據包。兩側分別啓動,在轉發關係創建以前,android是不會受到UDP數據包。一旦轉發關係1098:1097創建以後UDP服務端就會收到PC端的消息。

如上圖所示,右側控制檯爲PC端socket發送內容,左側logcat爲android設備中的socket服務器收到的內容。固然反過來,能夠不須要轉發直接向PC端發送消息。
以上。
ps,本人在實現過程當中,用android模擬器向PC主廣播數據包時,PC接收不到,不知道各位有沒有遇到這種狀況,求解答!!