android連接tcp
㈠ android 切換網路時候TCP長連接怎麼重連
1:android客戶端通過service在後台通過servreScoket不斷的accept,一旦有相應的socket到達,則啟動一個線程去處理
2::在線程中處理完返回給我們android客戶端的消息或任務之後,要將這種結果表現在ui上,這個步驟方法就比較多了,例如你可以發一個廣播來通知ui,或者你可以通過一個static的handler來處理
*************************************service中的關鍵代碼
㈡ 我怎樣才能連接與亞行至Android通過TCP
手動處理 從您的設備,如果它是植根 根據對XDA開發後,您可以啟用adb通過WiFi從裝置su
setprop service.adb.tcp.port 5555
stop adbd
start adbd
並且您可以禁用它,並返回亞行與監聽USBsetprop service.adb.tcp.port -1
stop adbd
start adbd
從電腦,如果你有USB連接已經 這是更容易切換無線網路,如果你已經有了USB訪問。從該行已在設備通過USB介面,連接問題adb tcpip 5555
adb connect 192.168.0.101:5555
一定要更換192.168.0.101與實際分配給您的設備的IP地址。 告訴亞行後台程序返回到監聽通過USBadb usb
應用自動化進程 也有在谷歌播放的自動執行此過程的幾個應用程序 CodeGo.net,快速搜索建議adbWireless,支持WiFiadb和adb的WiFi。所有這些都需要root許可權,但adbWireless需要更少的許可權。
2. 這是非常簡單的。 首先確保你的手機是植根。 從市場上下載一個終端模擬器(有很多是free的)。 請確保您的Android連接到您的無線網路,並獲得無線IP地址。 打開終端程序並鍵入:su
setprop service.adb.tcp.port 5555
stop adbd
start adbd
現在去(假設你視窗)在桌面上創建一個快捷方式為「cmd.exe的」(不含引號)。 右鍵單擊CMD快捷方式並選擇"Run as Administrator"改變你的android-sdk-windows\tools folder類型:adb connect ***wifi.ip.address***:5555
(example: adb connect 192.168.0.105:5555)
亞行現在應該說你已連接。 注意:如果你太快給它可能會失敗。所以,如果你說這是行不通的嘗試至少2 5秒鍾的時間間隔。
3. 我知道這是舊的,但我想補充我的2美分- 我需要得到兩個USB和TCPIP工作的adb(不要問),所以我做了以下(使用方向其他人張貼的XDA開發) 運用adb shell:su
#set the port number for adbd
setprop service.adb.tcp.port 5555
#run the adbd daemon *again* instead of doing stop/start, so there
#are 2 instances of adbd running.
adbd &
#set the port back to USB, so the next time adb is started it's
#on USB again.
setprop service.adb.tcp.port -1
exit
4. 正如布賴恩說: 根據對XDA開發後,您可以啟用adb通過WiFi從裝置 對應setProp service.adb.tcp.port 5555 停止adbd 啟動adbd 並且您可以禁用它,並返回亞行與監聽USB 對應setProp service.adb.tcp.port-1 停止adbd 啟動adbd 如果你有USB連接已經,它是更容易切換無線網路。從該行已在設備通過USB介面,連接問題 亞行TCPIP 5555 ADB連接192.168.0.101:5555 告訴亞行後台程序返回到監聽通過USB 也有在Android Market上的幾個應用程序能自動完成這些過程。 它works.You只需要訪問Android shell,然後輸入 另外一個(容易)解決方案是目前市場上:adbWireless,它會自動設置您的手機。 根是必須的!為...
5. 從adb --helpconnect <host>:<port> - connect to a device via TCP/IP
順便說那行選項。 你應該嘗試將手機連接到你的無線網路,然後得到它的IP從您的路由器,它不會工作,對 埠是5554
6. 您保存的adb路徑到您的Windows路徑 在Android激活調試模式 連接到PC 提示(有管理員右)類型:adb的TCPIP 5555 斷開平板電腦,或從電腦智能手機 提示符下鍵入:ADB連接IPADDRESS(IP地址為您的平板電腦或智能手機的DHCP / IP地址,您可以通過無線網路找到->電流 現在,提示你應該看到類似的結果:連接到xxx.xxx.xxx.xxx:5555
7.adb tcpip 5555
奇怪,但是這只是工作,如果我有USB電纜連接,然後我就可以拔掉,並為它去與一切ADB。 而返回時,adb usb
只會工作連接。 沒關系,如果我發出setprop service.adb.tcp.port 5555
或setprop service.adb.tcp.port -1
然後停止和啟動adbd,我仍然需要電纜或這是行不通的。 所以,如果我的亞行不工作,我敢打賭,我將無法使亞行通過WiFi兩種。
8. 你可以ssh本地埠轉發。但它仍然涉及電纜。 您的USB連接(主機)與一個sshd運行。 在遠程(遊客)個人電腦開始能夠portforwarding /隧道的ssh客戶端端。 例如:砰砰-L 5037:本地主機:5037 這種結構給我的設備連接到虛擬機。 到是不夠穩定(在調試過程中) SSH隧道工程為自由和更可靠。
9. 我不知道如何連接的設備,而在所有的任何一個USB連接,但如果你能,也許在您連接它可以通過發出切換adbd到TCP模式adb tcpip <port>
從終端,從任何PC上通過連接到您的設備通過WiFi:adb connect <ip>:<port>
也許也有可能從該裝置上的終端切換到TCP模式。
10. 我覺得其他的答案就簡單得多了adbWireless: 只需在手機上安裝一個應用程序切換調試通過wifi,安裝一個Eclipse插件,你就大功告成了。
11. 要連接您的TCP埠 請確保您的系統和設備連接到網路 1。打開控制台的cmd.exe 2,型號ADB TCPIP 5555 3。至系統->選項-> USB調試unchek它TCPIP連接 4.type ADB連接192.168.1.2這是您的設備ip地址 5。連接到192.168.1.2 如果你錯誤:未找到設備 連接設備到系統然後按照 為紮根設備 對應setProp service.adb.tcp.port 5555 停止adbd 啟動adbd
12. 在我的系統是這樣的: 我在我的Linux shell中的Android設備,一個簡單的「使用ifconfig」沒有我的IP地址。我只好類型: 用ifconfig eth0 -或- 加上netcfg 讓我的IP地址。 (我知道是eth0的配置,我看到它在我的dmesg)然後我做了: 對應setProp service.adb.tcp.port-1 停止adbd 啟動adbd 然後在我的Win7盒(一個運行Eclipse 3.7.1)。我打開提示 \\ Android的SDK \\平台工具> 沒有以管理員身份運行。然後我做了一個 ADB連接12.345.678.90 我從來沒有把一個埠。如果我做了 亞行TCPIP 5555 它說,它無法找到該設備,然後沒有出現在我的「亞行的設備」列表中。即這只是工作,如果我不這樣做上面。 我可以做一個「亞殼」與我的Android設備。但我的Android設備不現在出現在我的運行->運行配置-> Target選項卡。在另一方面,如果我把目標選項卡設置為自動。後來,當我通過運行我的應用程序運行->運行它並運行我的Android設備上,即使我的Android設備甚至沒有列為我的目標之一。
13. 要使用TCP和USB模式之間切換只需你可以將它添加到/init.rc:on property:service.adb.tcp.port=*
restart adbd
on property:service.adb.tcp.enable=1
setprop service.adb.tcp.port 5555
on property:service.adb.tcp.enable=0
setprop service.adb.tcp.port -1
現在你財產service.adb.tcp.enable啟用或禁用偵聽埠5555。運行netstat以檢查它是否在聽。正如你可以看到它也會觸發,如果你想改變service.adb.tcp.port手動。
14. 使用adbwireless應用程序,使手機,亞行從Windows機器連接到它對話。在手機上的應用程序adbwireless告訴你如何連接到它,給人的IP地址和一切。 要少得多有趣的選擇是通過USB進行連接,告訴亞行通過TCPIP 5555手機TCPIP,然後斷開USB,ADB連接。這是更難通過這種方式,你必須找出手機的IP地址,你自己(adbwireless告訴你的IP),你必須通過USB進行連接,你必須運行adb的TCPIP(adbwireless需要的是照顧過)。 所以:在手機上安裝adbwireless。使用它。這是可能的,我這樣做經常在Linux和Windows上。
15. 我放在一起自動啟用和通過TCP連接adb,通過USB連接的設備的批處理文件。有了它,你不必把在IP手動。@echo off
setlocal
REM Use a default env variable to find adb if possible
if NOT "%AndroidSDK%" == "" set PATH=%PATH%;%AndroidSDK%\platform-tools
REM If off is first parameter then we turn off the tcp connection.
if "%1%" == "off" goto off
REM Set vars
set port=%1
set int=%2
if "%port%" == "" set port=5557
if "%int%" == "" set int=wlan0
REM Enable TCP
adb -d wait-for-device tcpip %port%
REM Get IP Address from device
set shellCmd="ip addr show %int% | grep 'inet [0-9]{1,3}(\.[0-9]{1,3}){3}' -oE | grep '[0-9]{1,3}(\.[0-9]{1,3}){3}' -oE"
for /f %%i in ('adb wait-for-device shell %shellCmd%') do set IP=%%i
REM Connect ADB to device
adb connect %IP%:%port%
goto end
:fail
echo adbWifi [port] [interface]
echo adbWifi off
goto end
:off
adb wait-for-device usb
㈢ Android網路請求知識(三)授權,TCP/IP,HTTPS建立過程
由身份或持有的令牌確認享有的許可權,登錄過程實質上的目的也是為了確認許可權。
Cookie是客戶端給伺服器用的,setCookie是伺服器給客戶端用的。cookie由伺服器處理,客戶端負責存儲
客戶端發送cookie:賬戶和密碼
服務端收到後確認登錄setCookie:sessionID=1,記下sessionID
客戶端收到sessionID後記錄,以後請求服務端帶上對比記錄下sessionID,說明已經登錄
會話管理:登錄狀態,購物車
個性化:用戶偏好,主題
Tracking:分析用戶行為
XXS:跨腳本攻擊,及使用javaScript拿到瀏覽器的cookie之後,發送到自己的網站,以這種方式來盜用用戶Cookie。Server在發送Cookie時,敏感的Cookie加上HttpOnly,這樣Cookie只能用於http請求,不能被JavaScript調用
XSRF:跨站請求偽造。Referer 從哪個網站跳轉過來
兩種方式:Basic和Bearer
首先第三方網站向授權網站申請第三方授權合作,拿到授權方頒發的client_id和client_secret(一般都是appid+appkey的方式)。
在這就過程中申請的client_secret是伺服器持有的,安全起見不能給客戶端,用服務端去和授權方獲取用戶信息,再傳給客戶端,包括④,⑤的請求過程也是需要加密的。這才是標準的授權過程。
有了access_token之後,就可以向授權方發送請求來獲取用戶信息
步驟分析就是上面的內容,這里把第4,6,8請求的參數分析一下
第④步參數:
response_type:指授權類型,必選,這里填固定值『code』
client_id:指客戶端id,必選,這里填在平台報備時獲取的appid
redirect_uri:指重定向URI,可選
scope:指申請的許可權范圍,可選
state:指客戶端當前狀態,可選,若填了,則認證伺服器會原樣返回該值
第⑥步參數:
grant_type:指使用哪種授權模式,必選,這里填固定值『authorization_code』
code:指從第⑤步獲取的code,必選
redirect_uri:指重定向URI,必選,這個值需要和第④步中的redirect_uri保持一致
client_id:指客戶端id,必選,這里填在平台報備時獲取的appid
client_secret:指客戶端密鑰,必選,這里填在平台報備時獲取的appkey
第⑧步參數:
access_token:指訪問令牌,必選,這里填第⑦步獲取的access_token
token_type:指令牌類型,必選,大小寫不敏感,bearer類型 / mac類型
expires_in:指過期時間,單位秒,當其他地方已設置過期時間,此處可省略該參數
refresh_token:指更新令牌,可選,用即將過期token換取新token
scope:指許可權范圍,可選,第④步中若已申請過某許可權,此處可省略該參數
我們在上面的第八步中會有refresh_token的參數,這個在實際操作中也比較常見
有時候我們在自己的項目中,將登陸和授權設計成類似OAuth2的過程,不過去掉Authorization code。登陸成功返回access_token,然後客戶端再請求時,帶上access_token。
我們常常會說到TCP/IP,那到底是什麼呢。這就需要講到網路分層模型。TCP在傳輸層,IP在網路層。那為什麼需要分層?因為網路不穩定,導致需要重傳的問題。為了提高傳輸效率我們就需要分塊,在傳輸層中就會進行分塊。TCP還有兩個重要的內容就是三次握手,四次分手。
HTTPS 協議是由 HTTP 加上TLS/SSL協議構建的可進行加密傳輸、身份認證的網路協議,主要通過數字證書、加密演算法、非對稱密鑰等技術完成互聯網數據傳輸加密,實現互聯網傳輸安全保護
1.客戶端通過發送Client Hello報文開始SSL通信。報文中包含客戶端支持的SSL的指定版本、加密組件列表(所使用的加密演算法及密鑰長度),客戶端隨機數,hash演算法。
2.伺服器可進行SSL通信時,會以Server Hello報文作為應答。和客戶端一樣,在報文中包含SSL版本以及加密組件,服務端隨機數。伺服器的加密組件內容是從接收到客戶端加密組件內篩選出來的。
3.之後伺服器發送Certificate報文。報文中包含公開密鑰證書。一般實際有三層證書嵌套,其實像下面圖二直接用根證書機構簽名也是可以的,但是一般根證書機構比較忙,需要類似中介的證書機構來幫助。
4.最後伺服器發送Server Hello Done報文通知客戶端,最初階段的SSL握手協商部分結束。
5.SSL第一次握手結束後,客戶端以Client Key Exchange報文作為回應。報文中包含通信加密中使用的一種被稱為Pre-master secret的隨機密碼串。該報文已用步驟3中的公開密鑰進行加密。
6.接著客戶端繼續發送Change Cipher Spec報文。該報文會提示伺服器,在此報文之後的通信會採用Pre-master secret密鑰加密。
7.客戶端發送Finished報文。該報文包含連接至今全部報文的整體校驗值。這次握手協商是否能夠成功,要以伺服器是否能夠正確解密報文作為判定標准。
8.伺服器同樣發送Change Cipher Spec報文。
9.伺服器同樣發送Finished報文。
10.伺服器和客戶端的Finished報文交換完畢之後,SSL連接就算建立完成。當然,通信會受到SSL的保護。從此處開始進行應用層協議的通信,即發送HTTP響應。
11.應用層協議通信,即發送HTTP響應。
12.最後由客戶端斷開連接。斷開連接時,發送close_notify報文。這步之後再發送TCP FIN報文來關閉與TCP的通信。
利用客戶端隨機數,服務端隨機數,per-master secret隨機數生成master secret,再生成客戶端加密密鑰,服務端加密密鑰,客戶端MAC secert,服務端MAC secert。MAC secert用於做報文摘要,這樣能夠查知報文是否遭到篡改,從而保護報文的完整性。
Android網路請求知識(一)HTTP基礎概念
Android網路請求知識(二)對稱和非對稱加密、數字簽名,Hash,Base64編碼
Android網路請求知識(三)授權,TCP/IP,HTTPS建立過程
㈣ Android Http連接和TCP連接的區別
Http是應用層協議,TCP是網路層協議,應用層在TCP/IP四層架構中位於TCP的上一層。
建立Http連接在實現時有以下兩種方式:
1、[java] view plain
DefaultHttpClient http = new DefaultHttpClient();
HttpGet method = new HttpGet(url);
HttpResponse response =http.execute(method);
2、[java] view plain
URL url = new URL(uri);
HttpURLConnection connection = (HttpURLConnection)
url.openConnection();
connection.connect();
而TCP連接在實現時要藉助Socket(套接字 IP+埠號)
[java] view plain
Socket s = new Socket("localhost", 12345);
區別從這兩個連接的實現方式就可以看出來,HTTP連接需要指明資源的URL,發出請求的應用不知道伺服器的IP,雖然域名伺服器也是要把域名解析成IP地址,但不屬於應用所關心的范疇,是網路層應該完成的工作。所以Http連接屬於無狀態的短連接,若再請求其他數據,需要再重新建立連接。客戶端向伺服器發送請求後,伺服器才知道客戶端的存在。
TCP連接實現時需要指明IP地址和埠號,就可以跟目的主機通過三次握手建立聯系,該連接一直保持直到某一方提出取消連接,通過四次握手關閉連接。Socket支持TCP/UDP協議,如果使用TCP協議,那麼socket連接就是TCP連接。論文提到的應用場景是手機與雲端的伺服器建立聯系,因為要保持連接並指定連接的建立時間,所以在這種場景下使用TCP連接最合適。3G網路不支持端到端建立TCP連接,因為它是client-server模式,所以需要通過雲端伺服器的輔助來實現手機的端到端通信。
㈤ Android推送SDK(9)-TCP網路問題
主目錄見: Android高級進階知識(這是總目錄索引)
[written by 無心追求 ]
常
把Http和TCP連接服務做區分導致IM的TCP使用80埠連接進來的時候被誤
識別成是一個Http請求,所以就對IM的TCP數據流(TLV格式)進行解析導
致報錯返回了一個Http請求報錯的網頁的Html數據,具體返回的數據格式
客戶端列印是:
以上是客戶端TCP數據流read到100位元組列印出來的數據,是一個Http請求
失敗返回Http狀態碼為400的網頁Html數據
以上是tcpmp抓包信息,從抓包信息中可以得知返回的數據確實是一個
Http請求失敗的網頁,對比客戶端程序log列印是吻合的
式的數據,所以對read到的數據進行常規的TLV數據解析導致程序解析報錯
(數組越界):
客戶端發生數據解析報錯之後會認為當前接收到的數據已經不正確,同時
也會認為後面接續讀取的數據也將不正確,所以會把socket連接關閉重連
:
應該下調心跳周期,但是舊版(1.0.1Realease-1.0.6Realease版本)存在
不足,並沒有對此做過濾處理,所以會不斷的下調心跳
斷線後會馬上重連
接斷開的域名和埠再次嘗試重連,在重試重連失敗的時候才會去切換域
名或者埠,而遇到這種情況,每次嘗試重連TCP都能連接成功,連接成功
之後,數據解析失敗又把TCP連接斷開,然後再拿原來的域名和埠,再重
連,再斷開,如此陷入死循環,無法切換域名或者埠,斷線重連頻率很
高:
TCP連接IM伺服器gw.im.okii.com成功,連接埠為80
入的TCP數據為323個位元組
的數據進行解析
srcPos=2 dst.length=121 dstPos=0 length=121表示數據解析報錯,數組
越界
誤的識別成Http短連接
不下調心跳間隔,避免心跳誤下調,影響心跳探測的准確性
時間間隔遞增重連,避免頻繁的重連
一些常用的埠,例如8080,443,1000一下的埠等都不能使用,避免出
現類似的問題
和埠去再次連接IM伺服器導致無法跳出這個域名和埠連接造成的異常
,如果客戶端有成功切換域名或者埠,那麼遇到上述情況會立即切換到
8000埠,次數連接就會恢復正常
有上傳大數據的手錶分析來看全部都恢復正常使用
111.44.228.186這個地址(正確的應該是106.75.86.52),而被誤識別成
Http短鏈接,然後返回一個錯誤的網頁html數據,然後客戶端接收到數據
後解析報錯,導致頻繁的斷線重連和心跳下調
跳誤下調,重連頻繁,與香港的原因類似
gw.im.okii.com本地dns解析出來的ip為111.44.228.186,由此確認是被劫
持了
客戶端對接收到的TCP數據解析異常,數
組越界
客戶端在數據解析異常後斷線
連接斷開後心跳下調
㈥ 關於Android tcp連接
安卓的主線程中是不能用耗時性的操作讀寫,所以,把SOCKET讀寫操作都要放到線程中。
可以用即時線程的辦法。參考我的SOCKET客戶端。
//--------Socket服務端----------------------
void dispClients()
{ //顯示所有客戶
int n=vector.size();
String ss="\n"+n+" clients:\n";
for (int i=0;i<vector.size();i++)
{
Socket sk=vector.get(i);
String ip=sk.getInetAddress().toString();
String port=""+sk.getPort();
ss+=""+ip+","+port+"\n";
}
textView1.setText(ss);
}
void writeSocket(Socket sk,String s)
{ // 向客戶端Socket發字元串
DataOutputStream outf;
try
{
outf=new DataOutputStream(sk.getOutputStream());
if (!sk.isClosed())
outf.writeUTF(s);
}
catch(Exception e)
{
try
{
setTitle("err");
sk.close(); // 對方已關閉
}
catch(Exception e1)
{
}
}
}
void writeSock(final Socket sk,final String s)
{ // 子線程中向客戶端Socket發字元串
new Thread(new Runnable()
{
@Override
publicvoid run()
{
writeSocket(sk,s);
}
}).start();
}
void sendAll(final String s)
{ // 向所有管理中的客戶Socket發串
boolean del=false;
for (int i=0;i<vector.size();i++)
{
Socket sk=vector.get(i);
if (sk.isClosed())
{
vector.remove(i); // 已斷開的連接
del=true;
}
else
writeSock(sk,s);
}
if (del)
{ // 客戶端有變化,通知主程序刷新顯示
Message msg=sHandler.obtainMessage(0,"");
sHandler.sendMessage(msg);
}
}
void readSocket(Socket sk)
{ // 服務端讀Socket
DataInputStream inf;
try
{
inf=new DataInputStream(sk.getInputStream());
while(sk.isConnected() && !sk.isClosed())
{
String s=inf.readUTF();
if (s.length()>0)
{ // 讀到字元串後,通知主程序處理
String ip=sk.getInetAddress().toString();
String port=""+sk.getPort();
s=ip+","+port+":"+s+"\n";
Message msg=sHandler.obtainMessage(1,s);
sHandler.sendMessage(msg);
}
}
}
catch(Exception e)
{
}
}
void readSock(final Socket sk)
{ // 子線程中讀
new Thread(new Runnable()
{
@Override
publicvoid run()
{
readSocket(sk);
}
}).start();
}
void listen(ServerSocket ssk) // 接受多個客戶端連接請求
{
while (!ssk.isClosed())
try
{
Socket sk=ssk.accept();
vector.add(sk); // 有客戶連接
readSock(sk);
// 通知刷新客戶列表
Message msg=sHandler.obtainMessage(0,"");
sHandler.sendMessage(msg);
}
catch(Exception e)
{
}
}
void listen() // 線程接受多個客戶端連接請求
{
new Thread(new Runnable()
{
@Override
publicvoid run()
{
listen(serverSocket);
}
}).start();
}
//---------Socket客戶端----------------------------------
cHandler=new Handler()
{ // 客戶端消息處理器
@Override
public void handleMessage(Message msg)
{
String s=msg.obj.toString();
textView2.append(s);
}
};
clientRead("127.0.0.1",9003);
// clientRead("10.0.2.15",9003);
textView2=(TextView)findViewById(R.id.textView2);
textView2.setText("");
editText1=(EditText)findViewById(R.id.editText1);
button1=(Button)findViewById(R.id.button1);
button1.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
try
{
String s=editText1.getText().toString();
writeSock(clientSocket,s);
}
catch(Exception e)
{
}
} //public
});
button2=(Button)findViewById(R.id.button2);
button2.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
try
{
clientSocket.close();
String s="中華人民共和國";
Message msg=sHandler.obtainMessage(1,s);
sHandler.sendMessage(msg);
}
catch(Exception e)
{
}
} //public
});
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{ // 按返回鍵的退出處理
if (keyCode == KeyEvent.KEYCODE_BACK )
{
try
{ // 防止出現埠已綁定的錯誤
serverSocket.close();
finish();
System.exit(0);
}
catch(Exception e)
{
}
}
return(false);
}
㈦ Android Http連接和TCP連接的區別
http是應用層協議,tcp是傳輸層協議,tcp為http提供服務。tcp負責了數據傳輸的可靠性。而Http是典型的利用tcp實現短連接,客戶端發出一次請求,伺服器回應後立刻斷開!tcp還能實現長連接來實現像即使通訊和推送。不只是安卓,在任何網路設備都適用這個原理!