公司裡需要設置proxy才能連接外網,proxy是http://10.193.250.16:3128,dns是10.193.250.15。這種環境下Android模擬器中的browser無法直接連接internet. Android模擬器的每個實例運行在一個虛擬的路由器/防火牆服務後面, 以便和宿主機的網路介面隔離開來。一個類比設備不可能看到宿主機器,或者其它的類比設備實例, 也就是說,它只能看到自己通過乙太網連接到防火牆。每個模擬器實例的虛擬路由器管理著10.0.2/24這個網路位址空間,即,被路由器管理的所有的位址,都是以10.0.2.x的形式存在。
被模擬器/路由器預先分配的位址是:
10.0.2.1 路由器/閘道位址
10.0.2.2 宿主機loopbackup介面的別名(也就是宿主機的127.0.0.1)
10.0.2.3 第1個DNS伺服器:[net.dns1]
10.0.2.4/10.0.2.5/10.0.2.6 可選的第2/3/4個DNS(如果有的話)
10.0.2.15 模擬器設備自己的網路/乙太網介面:[net.gprs.local-ip]
127.0.0.1 模擬器設備自己的loopbackp介面

 

一般情況下模擬器的IP位址與宿主電腦(IP一般為192.168.1.100之類的私有位址)不在同一個網段,所以就會出現宿主電腦可以上網但是模擬器不能上網的情況。 要解決此問題,需要為模擬器設置與宿主電腦相同的http代理和dns伺服器等屬性。 解決的過程如下: 一、設置http代理
1) 檢查資料庫檔/data/data/com.android.providers.settings/databases/settings.db是否存在,如果存在則繼續;
2) 執行sqlite3來設置http代理: 首先進入資料庫: sqlite3 /data/data/com.android.providers.settings/databases/settings.db
執行以下sqlite3命令來設置http代理:
INSERT INTO system VALUES(99,'http_proxy','10.193.250.16:3128');
其中“10.193.250.16:3128”就是http代理,視具體網路參數而定;或者使用另外的代理:
INSERT INTO system VALUES(99,'http_proxy','10.193.118.30:3128'); SELECT * FROM system where _id=99; 3)
若要刪除http代理,則:
sqlite3 /data/data/com.android.providers.settings/databases/settings.db
而後執行sql命令:
DELETE FROM system WHERE _id=99;
4) 若要修改http代理:
sqlite3 /data/data/com.android.providers.settings/databases/settings.db
而後執行sql命令:
UPDATE system SET value ='10.193.250.16:3128' WHERE _id=99; UPDATE system SET value ='10.193.118.30:3128' WHERE _id=99;
------------------------------------------------------------
5) *** 臨時修改http代理:
在PC的命令列上執行:
export SP="[[:space:]]"
export proxy_key=`adb shell getprop | grep proxy | sed -e "s/\[\(.*\)\]${SP}*:${SP}*\[.*\]/\1/"`
adb shell setprop ${proxy_key} 10.193.250.16:3128
*** 若要臨時刪除http代理:
adb shell setprop ${proxy_key} “”
[在模擬器中,http代理對應的系統屬性(即$proxy_key)為: "net.gprs.http-proxy"]. 
------------------------------------------------------------
注):在Android程式設計中可使用以下代碼去讀取此http_proxy:
String my_http_proxy = Settings.Secure.getString( getContentResolver(), Settings.Secure.HTTP_PROXY);frameworks/base/core/java/android/provider/Settings.java
其中有這樣一行:public static final class Secure extends NameValueTable {...}
Secure內部類的getString()/getInt()/../ 方法所使用的資料庫CONTENT_URI為 content://settings/system,
實際就對應資料庫”/data/data/com.android.providers.settings/databases/settings.db“。 
------------------------------------------------------------


二、设置dns服务器
除http代理外,還要設置DNS: 這可在 PC上通過命令列來修改模擬器的property:
1) 查看原來的DNS: adb shell getprop | grep -i dns [net.dns1]: [10.0.2.3]
[net.dns2]: [10.0.2.4]
2)查看ubuntu PC機使用的DNS:
cat /etc/resolv.conf | grep -i nameserver nameserver 10.193.250.15
nameserver 10.193.250.13
3)修改模擬器使用的dns:
adb shell setprop net.dns1 10.193.250.15 注意:這樣設置的DNS重啟模擬器後會被恢復成10.0.2.3,所以要重新設置。
 
---------------------------------
以上過程也可在模擬器中直接設置:
1)啟動模擬器,然後進入 Settings->Wireless & networks->Mobile networks->Access Point Names
2)然後打開出現在清單中的access point;
3)然後下麵這樣設置:
- Proxy : your proxy address
- Port : your proxy port
- Username : your username if needed, or <Not set>
- Password : your password if needed, or <Not set> 三、與宿主機和其它模擬器的通訊
如果想在模擬器中訪問宿主機,請使用10.0.2.2這個IP。

 

模擬器的虛擬路由器應該可以處理所有出去的TCP和UDP連接,模擬器不能處理ICMP等協定。

 

為了能和在虛擬路由器之後的模擬器通信,必須在虛擬路由器上安裝網路埠重定向。連接到路由器上的某個指定的埠,路由器會轉發這些流量給模擬器設備。這需要用到模擬器主控台命令,或者使用ADB(Android Debug Bridge )工具。

 

假定A是宿主PC機, B是第一個模擬器,C是第二個模擬器。 在B和C,127.0.0.1指的是類比系統自身的環回介面,但10.0.2.2是指宿主機A的環回介面(又名 A:127.0.0.1,指向PC機)。10.0.2.15指的是模擬器自身的網路位址。執行adb devices 可以看到兩個模擬器設備是否啟動好,如下 List of devices attached
emulator-5554 device
emulator-5556 device 這裡將emulator-5554作為伺服器,將emulator-5556 作為用戶端。 1、在宿主機終端主控台視窗下執行:
telnet localhost 5554
這樣就連上伺服器emulator-555;

2、成功連接後,在telnet中繼續執行:

redir add tcp:5000:6000

這樣,所有在宿主機上5000埠的tcp通信都會被重定向到模擬器

emulator-5554的6000埠上。

 

添加成功後,我們可以用redir list命令來列出已經添加的映射埠,redir del可以進行刪除。

通訊時,伺服器端用以下java代碼打開server socket,並監聽用戶端的連接:


ServerSocket serverSocket = new ServerSocket(6000);

while(true) {

Socket client = serverSocket.accept();

...

}

 

用戶端則可用以下java代碼去連接伺服器:

 

Socket socket = new Socket("10.0.2.2", 5000); //注:這裡用的是宿主機的IP和被重定向的埠。
創作者介紹
創作者 shadow 的頭像
shadow

資訊園

shadow 發表在 痞客邦 留言(0) 人氣()