網絡開發(詳)


一.網絡管理

ConnectivityManager類來監控網絡連接的狀態,,配置錯誤處理等

1.檢查網絡狀態

ConnectivityManager cm =
        (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
 
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
boolean isConnected = activeNetwork.isConnectedOrConnecting();

 

2.檢查網絡類型

boolean isWiFi = activeNetwork.getType() == ConnectivityManager.TYPE_WIFI;

 

3.監控網絡狀態

<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>

 

 

二.HTTP通信

1.Http協議

一、HTTP協議詳解之請求

 

//請求行POST /reg.jsp HTTP/ (CRLF)       

1.User-Agent

1.1什麼是User-Agent

示例

谷歌Android
"Mozilla/5.0 (Linux; U; Android 2.2; en-us; Nexus One Build/FRF91) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1"

蘋果iPhone 4
"Mozilla/5.0 (iPhone; CPU iPhone OS 5_0_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Mobile/9A405"

蘋果iPad 2
"Mozilla/5.0 (iPad; CPU OS 5_0_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Mobile/9A405"

諾基亞N97
"Mozilla/5.0 (SymbianOS/9.4; Series60/5.0 NokiaN97-1/20.0.019; Profile/MIDP-2.1 Configuration/CLDC-1.1) AppleWebKit/525 (KHTML, like Gecko) BrowserNG/7.1.18124"

更多款手機的User-Agenthttp://www.zytrax.com/tech/web/mobile_ids.html

 

 

User-AgentHttp協議中的一部分,屬於頭域的組成部分,User Agent也簡稱UA。用較爲普通的一點來說,是一種向訪問網站提供你所使用的瀏覽器類型、操作系統及版本、CPU 類型、瀏覽器渲染引擎、瀏覽器語言、瀏覽器插件等信息的標識。UA字符串在每次瀏覽器 HTTP 請求時發送到服務器!

瀏覽器UA 字串的標準格式爲: 瀏覽器標識 (操作系統標識加密等級標識瀏覽器語言渲染引擎標識 版本信息

操作系統標識

  FreeBSD

  X11; FreeBSD (version no.) i386

  X11; FreeBSD (version no.) AMD64

  Linux

  X11; Linux ppc

  X11; Linux ppc64

  X11; Linux i686

  X11; Linux x86_64

  Mac

  Macintosh; PPC Mac OS X

  Macintosh; Intel Mac OS X

  Solaris

  X11; SunOS i86pc

  X11; SunOS sun4u

  Windows:

  Windows NT 6.1 對應操作系統 windows 7

  Windows NT 6.0 對應操作系統 windows vista

  Windows NT 5.2 對應操作系統 windows 2003

  Windows NT 5.1 對應操作系統 windows xp

  Windows NT 5.0 對應操作系統 windows 2000

  Windows ME

  Windows 98

加密等級標識

  N: 表示無安全加密

  I: 表示弱安全加密

  U: 表示強安全加密

瀏覽器語言

  在首選項 常規 語言中指定的語言

渲染引擎

  瀏覽器 使用 Presto 渲染引擎,格式爲: Presto/版本號

版本信息

  顯示 瀏覽器 真實版本信息,格式爲: Version/版本號

 

1.2、User-Agent的歷史

1993年,NCSA 發佈了首款 web 瀏覽器 Mosaic。它的 user-agent 字串非常簡潔:

  Mosaic/0.9雖然當時由於它對操作系統和平臺的依賴性,但是基本格式還是很簡單明瞭。在文本中,斜槓前面是產品名稱(可能會顯示爲 NCSA Mosaic 或是其他類似的字),斜槓後面是產品版本號。

  Netscape Communications 開發了 web 瀏覽器 Mozilla(當時號稱Mosaic 殺手)。他們首款公開發行版本: Netscape Navigator 2 user-agent 字串具有如下格式:

  Mozilla/Version [Language] (Platform; Encryption)Netscape 按之前的做法在 user-agent 字串的前半部分使用了產品名稱和產品版本,但在後面增加了下列信息:

  Language - 表示應用程序用的是哪個語言 Platform - 表示應用程序是在什麼操作系統和/或平臺中運行 Encryption - 表示應用程序包含了什麼安全加密類型。其中的值可能是U(128位加密)I(40位加密)N(沒加密)。 Netscape Navigator 2 user-agent 字串的示例:

  Mozilla/2.02 [fr] (WinNT; I)上面的字串指: Netscape Navigator 2.02 、法語 、Windows NT 40位加密。在當時,通過user-agent 字串中的產品名稱,可以正確判斷使用的是哪個 web 瀏覽器。Netscape Navigator 3 Internet Explorer 31996年,Netscape Navigator 3 發佈,它遠遠超過 Mosaic 成爲當時最流行的 web 瀏覽器。而user-agent 字串只有些小的變化:去掉了語言部分,多了個放操作系統或CPU的可選信息。格式如下:

  Mozilla/Version (Platform; Encryption [; OS-or-CPU description])在 Windows 系統中 Netscape Navigator 3 user-agent 字串的示例:

  Mozilla/3.0 (Win95; U)上面的字串指:Netscape Navigator 3 Windows 95 128 位加密。在 Windows 系統中,字串裏面不會顯示 OS 或 CPU 的信息。

  Netscape Navigator 3 發佈不久,微軟公佈了它的首款 web 瀏覽器: IE 3 ¹,但是 Netscape 是當時首選瀏覽器,大多數服務器在加載頁面前都會檢查 user-agent 是否爲該款瀏覽器。IE 如果不兼容Netscape user-agent 字串,使用 IE 的用戶就根本打不開這些頁面,於是造就瞭如下格式:

  Mozilla/2.0 (compatible; MSIE Version; Operating System)在 Windows 95 中 IE 3.02 user-agent 字串的示例:

  Mozilla/2.0 (compatible; MSIE 3.02; Windows 95)由於當時的瀏覽器嗅探只查 user-agent 字串中的產品名稱部分,結果 IE 搖身一變被識別成了 Mozilla,僞裝成 Netscape Navigator。這個做法引發了對瀏覽器識別的爭論。從此以後,瀏覽器真正的版本埋沒在了字串的中間。Netscape Communicator 4 Internet Explorer 4819978月,Netscape Communicator 4 發佈(發佈的名稱中 Navigator 換成了 Communicator),它的 user-agent 字串格式與 版本一致。Windows 98 中 版本的user-agent 字串如下:

  Mozilla/4.0 (Win98; I)Netscape 瀏覽器在更新時,版本也相應增加。4.79 版本的 user-agent 字串如下:

  Mozilla/4.79 (Win98; I)微軟發佈 IE 4 時,user-agent 字串更新了版本,格式如下:

  Mozilla/4.0 (compatible; MSIE Version; Operating System)在 Windows 98 中 IE 4 user-agent 字串的示例:

  Mozilla/4.0 (compatible; MSIE 4.0; Windows 98)可以看出,Mozilla 的版本與 IE 實際的版本一致,這樣就可以識別第4代瀏覽器了。但遺憾的是,不久 IE 4.5 馬上就發佈了(只在 Mac 平臺),雖然 Mozilla 版本仍是 4,但是 IE 的版本改成如下:

  Mozilla/4.0 (compatible; MSIE 4.5; Mac_PowerPC)此後,IE 的版本一直到 都沿用了這個模式。

  而 IE 8 的 user-agent 字串添加了呈現引擎(rendering engine)版本:

  Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)新增的呈現引擎非常重要!這樣 IE8 以 MSIE 7.0 兼容模式運行時,Trident 版本保持不變,而原先 IE7 user-agent 字串不包括 Trident 版本。這樣可以區分 IE7 與 IE8 運行的兼容模式。

  注意:別指望能從 Mozilla 版本中得到什麼靠譜的信息。

Gecko

  Gecko 是 Firefox 的呈現引擎。Gecko 首次開發是作爲 Mozilla 瀏覽器 Netscape 6 的一部分。Netscape 6 user-agent 字串的結構是面向未來的,新版本反應出從 4.x 版本的簡單變得較爲複雜,它的格式如下:

  Mozilla/MozillaVersion (Platform; Encryption; OS-or-CPU; Language; PrereleaseVersion)Gecko/GeckoVersion ApplicationProduct/ApplicationProductVersion爲了更好的理解上面的 Geckouser-agent 字串格式,下面來看看各種從基於 Gecko 瀏覽器中取得的字串。

  在 Windows XP 中的 Netscape 6.21

  Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:0.9.4) Gecko/20011128 Netscape6/6.2.1在 Linux 中的 SeaMonkey 1.1a:

  Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1b2) Gecko/20060823 SeaMonkey/1.1a在 Windows XP 中的 Firefox 2.0.0.11 :

  Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.11) Gecko/20071127 Firefox/2.0.0.11Mac OS X 中的 Camino 1.5.1:

  Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en; rv:1.8.1.6) Gecko/20070809 Camino/1.5.1上面都是基於 Gecko 的瀏覽器所取得的user-agent 字串,區別只是版本有所不同。Mozilla 版本 5.0 是自從首款基於 Gecko 發佈後就一直不變,而且以後有可能也不會變²

WebKit

  2003年,Apple 宣佈發佈首款他們自主開發的 web 瀏覽器:Safari。它的呈現引擎叫 WebKit。它是 Linux 中的 web 瀏覽器 Konqueror 呈現引擎 KHTML 的一個分支,幾年後,WebKit 的開源吸引了呈現引擎的開發人員。

  這款新瀏覽器和呈現引擎的開發人員也遇到了曾經 IE 3.0 類似的問題:怎樣才能溶入主流而不被踢出局?答案是:在 user-agent 字串中放詳盡的信息,以便騙取網站的信任使它與其它流行的瀏覽器兼容。user-agent字串格式如下:

  Mozilla/5.0 (Platform; Encryption; OS-or-CPU; Language) AppleWebKit/AppleWebKitVersion (KHTML, like Gecko) Safari/SafariVersion下面是示例:

  Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/124 (KHTML, like Gecko) Safari/125.1這又是個挺長的user-agent 字串,其中包括的信息既有 Apple WebKit 的版本,也有 Safari 的版本。凡是基於 WebKit 的瀏覽器都將自己僞裝成了 Mozilla 5.0,與基於 Gecko 瀏覽器完全一樣。但 Safari 的版本是瀏覽器的構建版本號(build number)Safari 1.25 user-agent 字串中號爲 125.1(如上所示)Safari 版本 user-agent 字串包括了實際的 Safari 版本:

  Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/522.15.5 (KHTML, like Gecko) Version/3.0.3 Safari/522.15.5其中的(KHTML, like Gecko)在 Safari 1.0 預覽版本中就有了,這字串部分是最耐人尋味又飽受詬病。Apple 的野心是爲了讓開發人員把 Safari 當成 Gecko,所以採取了當初微軟 IEuser-agent 的類似做法:Safari 是兼容 Mozilla 的,否則 Safari 用戶會認爲用的瀏覽器不受支持。

  而其它基於 WebKit 的瀏覽器與 Safari 不同的是,沒有上面說的這個情況,所以檢測斷定瀏覽器是否基於 WebKit 比看有沒有明確標 Safari 更有用。

Konqueror

  Konqueror 是款在 KDE Linux 桌面環境中的瀏覽器,基於 KHTML 開源呈現引擎。它只發布了在 Linux 的版本,但是擁有活躍的用戶羣。爲了兼容性最大化,user-agent 字串的格式也緊跟 IE 的後塵:

  Mozilla/5.0 (compatible; Konqueror/Version; OS-or-CPU)Konqueror 3.2 爲了與 WebKituser-agent 字串變化保持一致,它將 KHTML 作爲它的標識:

  Mozilla/5.0 (compatible; Konqueror/Version; OS-or-CPU) KHTML/KHTMLVersion (like Gecko)如下所示:

  Mozilla/5.0 (compatible; Konqueror/3.5; SunOS) KHTML/3.5.0 (like Gecko)Konqueror 和 KHTML 的版本號比較一致,唯一的區別就是下點處不同,比如Konquerer 3.5KHTML 3.5.1

Chrome

  Google Chrome 瀏覽器以 WebKit 作爲呈現引擎,JavaScript 引擎卻用了另一種。最初發布的版本是 0.2,它的 user-agent 字串格式是在 webKit 信息的基礎上又增加了如下:

  Mozilla/5.0 (Platform; Encryption; OS-or-CPU; Language) AppleWebKit/AppleWebKitVersion (KHTML, like Gecko) Chrome/ChromeVersion Safari/SafariVersionChrome 0.2user-agent 信息的示例如下:

  Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.13 (KHTML, like Gecko) Chrome/0.2.149.29 Safari/525.13雖我不敢完全保證,但很可能 WebKit 版本和 Safari 版本總會保持同步。

Opera

  Opera 瀏覽器默認 user-agent 字串是現代瀏覽器中最合理的--正確的標識了它自己及其版本。 在 Opera 8.0 前,它的user-agent 字串格式如下:

  Opera/Version (OS-or-CPU; Encryption) [Language]在 Windows XP 中 Opera 7.54 user-agent 字串示例:

  Opera/7.54 (Windows NT 5.1; U) [en]Opera 8 user-agent 字串的語言部分移到了括號內。

  Opera/Version (OS-or-CPU; Encryption; Language)在 Windows XP 中 Opera 8 user-agent 字串示例:

  Opera/8.0 (Windows NT 5.1; U; en)當時 Opera 做爲主流瀏覽器之一,它的 user-agent 字串是唯一使用產品名稱和版本完全真實的標識了它自己。但是由於大量的瀏覽器嗅探代碼在 Internet 上像蝗蟲飛過般只吃標 Mozilla 產品名的user-agent 字串,造成了 Opera user-agent 字串發生了完全的改變。

  Opera 9 user-agent 字串有兩種修改的方式:一種方式是將自己標識爲 Firefox 或 IE 瀏覽器。在這種方式下,user-agent 字串與 Firefox 或 IE 的幾乎一樣,只不過末尾附加了Opera及版本號。如下所示:

  Mozilla/5.0 (Windows NT 5.1; U; en; rv:1.8.1) Gecko/20061208 Firefox/2.0.0 Opera 9.50Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; en) Opera 9.50前一字串將 Opera 9.5 標識爲 Firefox 2。後一字串將 Opera 9.5 標識爲 IE 6,在兩個字串中都帶有 Opera 版本信息。雖然這種方式是作爲 Firefox 或 IE 打開的,但也能識別出 Opera。另一種方法則是瀏覽器 user-agent 字串標識僞裝成 Firefox 或 IE,同時也找不到Opera字串及其版本信息。這樣從字面上去區分 Opera 瀏覽器便成了不可能完成的任務

結論

user-agent 字串史可以說明曾對 user-agent 嗅探說不的原因:IE 想要將自己識別爲 Netscape 4Konqueror 和 WebKit 想要識別爲 FirefoxChrome 想要識別爲 Safari。這樣使得除 Opera 外所有瀏覽器的user-agent 嗅探區別很小,想要從一堆茫茫瀏覽器海洋中找出有用的標識太少了。關於嗅探要記住:一款瀏覽器與其它瀏覽器是兼容的,這樣造成了不能完全準確的斷定是哪款瀏覽器。

  比如說 Chrome ,它聲稱任何可以在 Safari 3 訪問的網站 Chrome 也都可以訪問,但是對檢測 Chrome 沒有一點用。爲了瀏覽器的兼容--這便是這個聲明的理由。

 

1.3user-agent作用

根據前面介紹的user-agent的歷史我們知道,通過user-agent不能完全準確的判斷是屬於那款瀏覽器。由於UA字符串在每次瀏覽器HTTP 請求時發送到服務器,所以服務器就可以根據它來做好多事。

比如:

1、統計用戶瀏覽器使用情況。有些瀏覽器說被多少人使用了,實際上就可以通過判斷每個IPUA來確定這個IP是用什麼瀏覽器訪問的,以得到使用量的數據。

2、根據用戶使用瀏覽器的不同,顯示不同的排版從而爲用戶提供更好的體驗。有些網站會根據這個來調整打開網站的類型,如是手機的就打開wap,顯示非手機的就打開pc常規頁面。用手機訪問谷歌和電腦訪問是不一樣的,這些是谷歌根據訪問者的UA來判斷的。 

既然知道了UA的作用,那麼其實客戶端也可以使用UA來做一些神奇的事。

比如:僞裝 user agent 來回避某些偵測特定瀏覽器才能讀取的網站。

如果使用Firefox瀏覽器插件User agent switcher,用戶就可以輕鬆地在不同UA之間切換,把自己僞裝成其他瀏覽器。這樣就可以在PC上預覽WAP或移動格式的網頁,比如專門爲iPhone設計的頁面

 

1.4、獲得user-agent的值

既然已經知道user-agenthttp的頭域,那我們在編程的時候就可以獲得它。

在 ASP.NET 中使用 Request.Header["User-Agent"] 得到瀏覽器的 User Agent,也可以使用 Request.UserAgent 來獲取;
Java 中使用 request.getHeader(User-Agent來獲得;
PHP 中相應使用:$_SERVER[HTTP_USER_AGENT]

JS中則使用navigator.userAgent來獲得(是否記得在客戶端經常使用它來做瀏覽器兼容呢)。

 

//消息報頭Accept:image/gif,image/x-xbitmap,image/jpeg,application/x-shockwave-flash,application/vnd.ms-excel,application/vnd.ms-powerpoint,application/msword,*/*(CRLF)

Accept-Language:zh-cn (CRLF)

Accept-Encoding:gzip,deflate (CRLF)

If-Modified-Since:Wed,05 Jan 2007 11:21:25 GMT (CRLF)

If-None-Match:W/"80b1a4c018f3c41:8317" (CRLF)

User-Agent:Mozilla/4.0(compatible;MSIE6.0;Windows NT 5.0) (CRLF)

Host:www.guet.edu.cn (CRLF)

Connection:Keep-Alive (CRLF)

(CRLF)

 

//請求正文

user=jeffrey&pwd=1234 

     以上是http請求的三部:請求行、消息報頭、請求正文。

 

     請求行以一個方法符號開頭,以空格分開,後面跟着請求的URI和協議的版本,格式如下:

Method Request-URI HTTP-Version CRLF  
     其中 Method表示請求方法(POSTGETPUTDELETE)Request-URI是一個統一資源標識符;HTTP-Version表示請求的HTTP協議版本;CRLF表示回車和換行。

 

二、HTTP協議詳解之響應篇

//狀態行HTTP/1.1 200 OK (CRLF)

 

//消息報頭Cache-Control: private, max-age=30

Content-Type: text/html; charset=utf-8

Content-Encoding: gzip

Expires: Mon, 25 May 2009 03:20:33 GMT

Last-Modified: Mon, 25 May 2009 03:20:03 GMT

Vary: Accept-Encoding

Server: Microsoft-IIS/7.0

X-AspNet-Version: 2.0.50727

X-Powered-By: ASP.NET

Date: Mon, 25 May 2009 03:20:02 GMT

Content-Length: 12173

 

//響應正文

     HTTP響應也是由三個部分組成,分別是:狀態行、消息報頭、響應正文

     狀態行格式如下:
          HTTP-Version Status-Code Reason-Phrase CRLF
     其中,HTTP-Version表示服務器HTTP協議的版本;Status-Code表示服務器發回的響應狀態代碼;Reason-Phrase表示狀態代碼的文本描述。

常見狀態代碼、狀態描述、說明:
200 OK      //客戶端請求成功
400 Bad Request  //客戶端請求有語法錯誤,不能被服務器所理解
401 Unauthorized //請求未經授權,這個狀態代碼必須和WWW-Authenticate報頭域一起使用 
403 Forbidden  //服務器收到請求,但是拒絕提供服務
404 Not Found  //請求資源不存在,eg:輸入了錯誤的URL
500 Internal Server Error //服務器發生不可預期的錯誤
503 Server Unavailable  //服務器當前不能處理客戶端的請求,一段時間後可能恢復正常

 

三、HTTP協議詳解之消息報頭

        HTTP消息由客戶端到服務器的請求和服務器到客戶端的響應組成。請求消息和響應消息都是由開始行(對於請求消息,開始行就是請求行;對於響應消息,開始行就是狀態行),消息報頭(可選),空行(只有CRLF的行),消息正文(可選)組成。

        HTTP消息報頭包括普通報頭、請求報頭、響應報頭、實體報頭。每一個報頭域都是由名字++空格+值 組成,消息報頭域的名字是大小寫無關的。

1、請求報頭
     請求報頭允許客戶端向服務器端傳遞請求的附加信息以及客戶端自身的信息。


常用的請求報頭

Accept請求報頭域用於指定客戶端接受哪些類型的信息。
Accept-Charset請求報頭域用於指定客戶端接受的字符集。
Accept-Encoding請求報頭域類似於Accept,但是它是用於指定可接受的內容編碼。
Accept-Language請求報頭域類似於Accept,但是它是用於指定一種自然語言。
Authorization請求報頭域主要用於證明客戶端有權查看某個資源。

Host請求報頭域主要用於指定被請求資源的Internet主機和端口號,它通常從HTTP URL中提取出來的。User-Agent請求報頭域允許客戶端將它的操作系統、瀏覽器和其它屬性告訴服務器。

2、響應報頭

     響應報頭允許服務器傳遞不能放在狀態行中的附加響應信息,以及關於服務器的信息和對Request-URI所標識的資源進行下一步訪問的信息。


常用的響應報頭
Location響應報頭域用於重定向接受者到一個新的位置。Location響應報頭域常用在更換域名的時候。
Server響應報頭域包含了服務器用來處理請求的軟件信息

3. 實體報頭

請求和響應消息都可以傳送一個實體。


常用的實體報頭
Content-Encoding指示已經被應用到實體正文的附加內容的編碼。

Content-Language實體報頭域描述了資源所用的自然語言。

Content-Length實體報頭域用於指明實體正文的長度,以字節方式存儲的十進制數字來表示。
Content-Type實體報頭域用語指明發送給接收者的實體正文的媒體類型。
Last-Modified實體報頭域用於指示資源的最後修改日期和時間。
Expires實體報頭域給出響應過期的日期和時間。

 

四、補充

1HTTP協議Content Lenth限制漏洞導致拒絕服務攻擊
使用POST方法時,可以設置ContentLenth來定義需要傳送的數據長度,例如ContentLenth:999999999,在傳送完成前,內 存不會釋放,攻擊者可以利用這個缺陷,連續向WEB服務器發送垃圾數據直至WEB服務器內存耗盡。這種攻擊方法基本不會留下痕跡。
2、爲了提高用戶使用瀏覽器時的性能,現代瀏覽器還支持併發的訪問方式,瀏覽一個網頁時同時建立多個連接,以迅速獲得一個網頁上的多個圖標,這樣能更快速完成整個網頁的傳輸。HTTP1.1中提供了這種持續連接的方式,而下一代HTTP協議:HTTP-NG更增加了有關會話控制、豐富的內容協商等方式的支持,來提供更高效率的連接。

 

.Java利用HTTP協議實現聯網和下載

Url的請求連接(Get方式)

String currentUrl=http://www.myWeb.com/login.jsp?userName='Devin'&passWord='mypassword'; //URL ?後面的內容爲HTTP請求的正文

URL url = new URL(currentUrl);

 

HttpURLConnection httpurlconnection = url.openConnection();

//下面的設置對應HTTP請求中的消息報頭

httpurlconnection.setRequestProperty("User-Agent",CommonValues.User_Agent);

httpurlconnection.setRequestProperty("Accept",CommonValues.Accept);

httpurlconnection.setRequestProperty("Accept-Charset",CommonValues.Accept_Charset);

httpurlconnection.setRequestProperty("Accept-Language",CommonValues.Accept_Language);

httpurlconnection.setRequestProperty("Connection",CommonValues.Connection);

httpurlconnection.setRequestProperty("Keep-Alive",CommonValues.Keep_Alive);

httpurlconnection.setConnectTimeout(CommonValues.ConnectionTimeOut);

httpurlconnection.setReadTimeout(CommonValues.ReadTimeOut);

             

httpurlconnection.connect();

            

int responsecode = httpurlconnection.getResponseCode();

             

if(responsecode == HttpURLConnection.HTTP_OK) //對應HTTP響應中狀態行的響應碼

{

//操作請求流,這裏對應HTTP響應中的響應正文

}

             

if (httpurlconnection != null

{

   httpurlconnection.disconnect();

}

 

 

HTTP請求:GETPOST方法的區別

  HTTP 定義了與服務器交互的不同方法,最基本的方法是 GET 和 POST

  1.Get是從服務器上獲取數據,Post是向服務器傳送數據。GET 用於信息獲取,是安全的和冪等的。安全的意味着該操作用於獲取信息而非修改信息,冪等的意味着對同一 URL 的多個請求應該返回同樣的結果。完整的定義並不像看起來那樣嚴格。

  2.GET請求請提交的數據放置在HTTP請求協議頭中,附加在url之後,以?分開與url分開;而POST提交的數據則放在實體數據中,即在HTML HEADER內提交。

  3.GET方式提交的數據最多只能有1024字節,而POST則沒有此限制。

  4.安全性問題。使用 Get 的時候,參數會顯示在地址欄上,而 Post 不會。所以,如果這些數據是中文數據而且是非敏感數據,那麼使用 get;如果用戶輸入的數據不是中文字符而且包含敏感數據,那麼還是使用 post爲好。

  5GetForm的默認方法。

 

 

Android網絡連接之HttpURLConnectionHttpClient

1.概念      

      HTTP 協議可能是現在 Internet 上使用得最多、最重要的協議了,越來越多的 Java 應用程序需要直接通過 HTTP 協議來訪問網絡資源。在 JDK 的 java.net 包中已經提供了訪問 HTTP 協議的基本功能:HttpURLConnection。但是對於大部分應用程序來說,JDK 庫本身提供的功能還不夠豐富和靈活。

      除此之外,在Android中,androidSDK中集成了ApacheHttpClient模塊,用來提供高效的、最新的、功能豐富的支持 HTTP 協議工具包,並且它支持 HTTP 協議最新的版本和建議。使用HttpClient可以快速開發出功能強大的Http程序。

2.區別

HttpClient是個很不錯的開源框架,封裝了訪問http的請求頭,參數,內容體,響應等等,

HttpURLConnectionjava的標準類,什麼都沒封裝,用起來太原始,不方便,比如重訪問的自定義,以及一些高級功能等。

 

URLConnection

HTTPClient

Proxies and SOCKS

Full support in Netscape browser, appletviewer, and applications (SOCKS: Version 4 only); no additional limitations from security policies.

Full support (SOCKS: Version 4 and 5); limited in applets however by security policies; in Netscape can't pick up the settings from the browser.

Authorization

Full support for Basic Authorization in Netscape (can use info given by the user for normal accesses outside of the applet); no support in appletviewer or applications.

Full support everywhere; however cannot access previously given info from Netscape, thereby possibly requesting the user to enter info (s)he has already given for a previous access. Also, you can add/implement additional authentication mechanisms yourself.

Methods

Only has GET and POST.

Has HEAD, GET, POST, PUT, DELETE, TRACE and OPTIONS, plus any arbitrary method.

Headers

Currently you can only set any request headers if you are doing a POST under Netscape; for GETs and the JDK you can't set any headers.  Under Netscape 3.0 you can read headers only if the resource was returned with a Content-length header; if no Content-length header was returned, or under previous versions of Netscape, or using the JDK no headers can be read.

Allows any arbitrary headers to be sent and received.

Automatic Redirection Handling

Yes.

Yes (as allowed by the HTTP/1.1 spec).

Persistent Connections

No support currently in JDK; under Netscape uses HTTP/1.0 Keep-Alive's.

Supports HTTP/1.0 Keep-Alive's and HTTP/1.1 persistence.

Pipelining of Requests

No.

Yes.

Can handle protocols other than HTTP

Theoretically; however only http is currently implemented.

No.

Can do HTTP over SSL (https)

Under Netscape, yes. Using Appletviewer or in an application, no.

No (not yet).

Source code available

No.

Yes.

3.案例

URLConnection

    String urlAddress = "http://192.168.1.102:8080/AndroidServer/login.do";  

    URL url;  

    HttpURLConnection uRLConnection;  

    public UrlConnectionToServer(){  

  

    } 

   //向服務器發送get請求

    public String doGet(String username,String password){  

        String getUrl = urlAddress + "?username="+username+"&password="+password;  

        try {  

            url = new URL(getUrl);  

            uRLConnection = (HttpURLConnection)url.openConnection();  

            InputStream is = uRLConnection.getInputStream();  

            BufferedReader br = new BufferedReader(new InputStreamReader(is));  

            String response = "";  

            String readLine = null;  

            while((readLine =br.readLine()) != null){  

                //response = br.readLine();                  response = response + readLine;  

            }  

            is.close();  

            br.close();  

            uRLConnection.disconnect();  

            return response;  

        } catch (MalformedURLException e) {  

            e.printStackTrace();  

            return null;  

        } catch (IOException e) {  

            e.printStackTrace();  

            return null;  

        }  

    }  

      

    //向服務器發送post請求

    public String doPost(String username,String password){  

        try {  

            url = new URL(urlAddress);  

            uRLConnection = (HttpURLConnection)url.openConnection();  

            uRLConnection.setDoInput(true);  

            uRLConnection.setDoOutput(true);  

            uRLConnection.setRequestMethod("POST");  

            uRLConnection.setUseCaches(false);  

            uRLConnection.setInstanceFollowRedirects(false);  

            uRLConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");  

            uRLConnection.connect();  

              

            DataOutputStream out = new DataOutputStream(uRLConnection.getOutputStream());  

            String content = "username="+username+"&password="+password;  

            out.writeBytes(content);  

            out.flush();  

            out.close();  

              

            InputStream is = uRLConnection.getInputStream();  

            BufferedReader br = new BufferedReader(new InputStreamReader(is));  

            String response = "";  

            String readLine = null;  

            while((readLine =br.readLine()) != null){  

                //response = br.readLine();                  response = response + readLine;  

            }  

            is.close();  

            br.close();  

            uRLConnection.disconnect();  

            return response;  

        } catch (MalformedURLException e) {  

            e.printStackTrace();  

            return null;  

        } catch (IOException e) {  

            e.printStackTrace();  

            return null;  

        }  

    } 

HTTPClient

String urlAddress = "http://192.168.1.102:8080/qualityserver/login.do";  

public HttpClientServer(){  

          

 }  

      

public String doGet(String username,String password){  

    String getUrl = urlAddress + "?username="+username+"&password="+password;  

    HttpGet httpGet = new HttpGet(getUrl);  

    HttpParams hp = httpGet.getParams();  

    hp.getParameter("true");  

    //hp.  

    //httpGet.setp      HttpClient hc = new DefaultHttpClient();  

    try {  

        HttpResponse ht = hc.execute(httpGet);  

        if(ht.getStatusLine().getStatusCode() == HttpStatus.SC_OK){  

            HttpEntity he = ht.getEntity();  

            InputStream is = he.getContent();  

            BufferedReader br = new BufferedReader(new InputStreamReader(is));  

            String response = "";  

            String readLine = null;  

            while((readLine =br.readLine()) != null){  

                //response = br.readLine();                  response = response + readLine;  

            }  

            is.close();  

            br.close();  

              

            //String str = EntityUtils.toString(he);              System.out.println("========="+response);  

            return response;  

        }else{  

            return "error";  

        }  

    } catch (ClientProtocolException e) {  

        // TODO Auto-generated catch block          e.printStackTrace();  

        return "exception";  

    } catch (IOException e) {  

        // TODO Auto-generated catch block          e.printStackTrace();  

        return "exception";  

    }      

}  

  

public String doPost(String username,String password){  

    //String getUrl = urlAddress + "?username="+username+"&password="+password;      HttpPost httpPost = new HttpPost(urlAddress);  

    List params = new ArrayList();  

    NameValuePair pair1 = new BasicNameValuePair("username", username);  

    NameValuePair pair2 = new BasicNameValuePair("password", password);  

    params.add(pair1);  

    params.add(pair2);  

      

    HttpEntity he;  

    try {  

        he = new UrlEncodedFormEntity(params, "gbk");  

        httpPost.setEntity(he);  

          

    } catch (UnsupportedEncodingException e1) {  

        // TODO Auto-generated catch block          e1.printStackTrace();  

    }   

      

    HttpClient hc = new DefaultHttpClient();  

    try {  

        HttpResponse ht = hc.execute(httpPost);  

        //連接成功          if(ht.getStatusLine().getStatusCode() == HttpStatus.SC_OK){  

            HttpEntity het = ht.getEntity();  

            InputStream is = het.getContent();  

            BufferedReader br = new BufferedReader(new InputStreamReader(is));  

            String response = "";  

            String readLine = null;  

            while((readLine =br.readLine()) != null){  

                //response = br.readLine();                  response = response + readLine;  

            }  

            is.close();  

            br.close();  

              

            //String str = EntityUtils.toString(he);              System.out.println("=========&&"+response);  

            return response;  

        }else{  

            return "error";  

        }  

    } catch (ClientProtocolException e) {  

        // TODO Auto-generated catch block          e.printStackTrace();  

        return "exception";  

    } catch (IOException e) {  

        // TODO Auto-generated catch block          e.printStackTrace();  

        return "exception";  

    }     

servletjson轉化: 

        resp.setContentType("text/json");  

        resp.setCharacterEncoding("UTF-8");  

        toDo = new ToDo();  

        List<UserBean> list = new ArrayList<UserBean>();  

        list = toDo.queryUsers(mySession);  

        String body;  

 

        //設定JSON          JSONArray array = new JSONArray();  

        for(UserBean bean : list)  

        {  

            JSONObject obj = new JSONObject();  

            try  

            {  

                 obj.put("username", bean.getUserName());  

                 obj.put("password", bean.getPassWord());  

             }catch(Exception e){}  

             array.add(obj);  

        }  

        pw.write(array.toString());  

        System.out.println(array.toString()); 

android端接收:

String urlAddress = "http://192.168.1.102:8080/qualityserver/result.do";  

        String body =   

            getContent(urlAddress);  

        JSONArray array = new JSONArray(body);            

        for(int i=0;i<array.length();i++)  

        {  

            obj = array.getJSONObject(i);  

            sb.append("用戶名:").append(obj.getString("username")).append("\t");  

            sb.append("密碼:").append(obj.getString("password")).append("\n");  

              

            HashMap<String, Object> map = new HashMap<String, Object>();  

            try {  

                userName = obj.getString("username");  

                passWord = obj.getString("password");  

            } catch (JSONException e) {  

                e.printStackTrace();  

            }  

            map.put("username", userName);  

            map.put("password", passWord);  

            listItem.add(map);  

              

        }  

          

        } catch (Exception e) {  

            // TODO Auto-generated catch block              e.printStackTrace();  

        }  

          

        if(sb!=null)  

        {  

            showResult.setText("用戶名和密碼信息:");  

            showResult.setTextSize(20);  

        } else  

            extracted();  

   

       //設置adapter           SimpleAdapter simple = new SimpleAdapter(this,listItem,  

                android.R.layout.simple_list_item_2,  

                new String[]{"username","password"},  

                new int[]{android.R.id.text1,android.R.id.text2});  

        listResult.setAdapter(simple);  

          

        listResult.setOnItemClickListener(new OnItemClickListener() {  

            @Override  

            public void onItemClick(AdapterView<?> parent, View view,  

                    int position, long id) {  

                int positionId = (int) (id+1);  

                Toast.makeText(MainActivity.this, "ID"+positionId, Toast.LENGTH_LONG).show();  

              

            }  

        });  

    }  

    private void extracted() {  

        showResult.setText("沒有有效的數據!");  

    }  

    //和服務器連接      private String getContent(String url)throws Exception{  

        StringBuilder sb = new StringBuilder();  

        HttpClient client =new DefaultHttpClient();  

        HttpParams httpParams =client.getParams();  

          

        HttpConnectionParams.setConnectionTimeout(httpParams, 3000);  

        HttpConnectionParams.setSoTimeout(httpParams, 5000);  

        HttpResponse response = client.execute(new HttpGet(url));  

        HttpEntity entity =response.getEntity();  

          

        if(entity !=null){  

            BufferedReader reader = new BufferedReader(new InputStreamReader  

                    (entity.getContent(),"UTF-8"),8192);  

            String line =null;  

            while ((line= reader.readLine())!=null){  

                sb.append(line +"\n");  

            }  

            reader.close();  

        }  

        return sb.toString();  

    } 

 

 

 

 

 

androidHttpURLConnection

1.HttpURLConnection連接URL1)創建一個URL對象

URL url = new URL(http://www.baidu.com/);

2)利用HttpURLConnection對象從網絡中獲取網頁數據

HttpURLConnection conn = (HttpURLConnection) url.openConnection();

3)設置連接超時

conn.setConnectTimeout(6*1000);

4)對響應碼進行判斷

if (conn.getResponseCode() != 200)    //Internet獲取網頁,發送請求,將網頁以流的形式讀回來

throw new RuntimeException("請求url失敗");

5)得到網絡返回的輸入流

InputStream is = conn.getInputStream();
6)String result = readData(is, "GBK"); //文件流輸入出文件用outStream.write
7)conn.disconnect();

總結:--記得設置連接超時,如果網絡不好,Android系統在超過默認時間會收回資源中斷操作.
--返回的響應碼200,是成功.
--Android中對文件流的操作和JAVA SE上面是一樣的.
--在對大文件的操作時,要將文件寫到SDCard上面,不要直接寫到手機內存上.
--操作大文件是,要一遍從網絡上讀,一遍要往SDCard上面寫,減少手機內存的使用.這點很重要,面試經常會被問到.
--對文件流操作完,要記得及時關閉.


2.Internet發送請求參數
步驟:
1)創建URL對象:URL realUrl = new URL(requestUrl);
2)通過HttpURLConnection對象,向網絡地址發送請求

HttpURLConnection conn = (HttpURLConnection) realUrl.openConnection();
3)設置容許輸出:conn.setDoOutput(true);
4)設置不使用緩存:conn.setUseCaches(false);
5)設置使用POST的方式發送:conn.setRequestMethod("POST");
6)設置維持長連接:conn.setRequestProperty("Connection", "Keep-Alive");
7)設置文件字符集:conn.setRequestProperty("Charset", "UTF-8");
8)設置文件長度:conn.setRequestProperty("Content-Length", String.valueOf(data.length));
9)設置文件類型:conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
10)以流的方式輸出.
總結:--發送POST請求必須設置允許輸出
--不要使用緩存,容易出現問題.
--在開始用HttpURLConnection對象的setRequestProperty()設置,就是生成HTML文件頭.


3.Internet發送xml數據XML格式是通信的標準語言,Android系統也可以通過發送XML文件傳輸數據.
1)將生成的XML文件寫入到byte數組中,並設置爲UTF-8:byte[] xmlbyte = xml.toString().getBytes("UTF-8");
2)創建URL對象,並指定地址和參數:URL url = new URL(http://localhost:8080/itcast/contanctmanage.do?method=readxml);
3)獲得鏈接:HttpURLConnection conn = (HttpURLConnection) url.openConnection();
4)設置連接超時:conn.setConnectTimeout(6* 1000);
5)設置允許輸出conn.setDoOutput(true);
6)設置不使用緩存:conn.setUseCaches(false);
7)設置以POST方式傳輸:conn.setRequestMethod("POST");           
8)維持長連接:conn.setRequestProperty("Connection", "Keep-Alive");
9)設置字符集:conn.setRequestProperty("Charset", "UTF-8");
10)設置文件的總長度:conn.setRequestProperty("Content-Length", String.valueOf(xmlbyte.length));
11)設置文件類型:conn.setRequestProperty("Content-Type", "text/xml; charset=UTF-8");
12)以文件流的方式發送xml數據:outStream.write(xmlbyte);
總結:
--我們使用的是用HTML的方式傳輸文件,這個方式只能傳輸一般在5M一下的文件.
--傳輸大文件不適合用HTML的方式,傳輸大文件我們要面向Socket編程.確保程序的穩定性--將地址和參數存到byte數組中:byte[] data = params.toString().getBytes();

 

(一)Java接口

主要類:

URL:資源定位符類

 

URLConnection:資源連接

 

HttpURLConnectiion:繼承自URLConnection                 

  

// 設置是否向httpUrlConnection輸出,因爲這個是post請求,參數要放在   

  // http正文內,因此需要設爲true, 默認情況下是false;   

  httpUrlConnection.setDoOutput(true);   

   

  // 設置是否從httpUrlConnection讀入,默認情況下是true;   

  httpUrlConnection.setDoInput(true);   

   

  // Post 請求不能使用緩存   

  httpUrlConnection.setUseCaches(false);   

   

  // 設定傳送的內容類型是可序列化的java對象   

  // (如果不設此項,在傳送序列化對象時,WEB服務默認的不是這種類型時可能拋java.io.EOFException)   

  httpUrlConnection.setRequestProperty("Content-type", "application/x-java-serialized-object");   

   

  // 設定請求的方法爲"POST",默認是GET   

  httpUrlConnection.setRequestMethod("POST");   

   

  // 連接,從上述第2條中url.openConnection()至此的配置必須要在connect之前完成,   

          httpUrlConnection.connect();

注:

a:) HttpURLConnectionconnect()函數,實際上只是建立了一個與服務器的tcp連接,並沒有實際發送http請求。 

    無論是post還是gethttp請求實際上直到HttpURLConnectiongetInputStream()這個函數裏面才正式發送出去。 
       b:) 在用POST方式發送URL請求時,URL請求參數的設定順序是重中之重, 
    對connection對象的一切配置(那一堆set函數) 
    都必須要在connect()函數執行之前完成。而對outputStream的寫操作,又必須要在inputStream的讀操作之前。 
    這些順序實際上是由http請求的格式決定的。 
    如果inputStream讀操作在outputStream的寫操作之前,會拋出例外: 
    java.net.ProtocolException: Cannot write output after reading input....... 
       
       c:) http請求實際上由兩部分組成, 
    一個是http頭,所有關於此次http請求的配置都在http頭裏面定義, 
           一個是正文content。 
    connect()函數會根據HttpURLConnection對象的配置值生成http頭部信息,因此在調用connect函數之前, 
    就必須把所有的配置準備好。 
       d:) http頭後面緊跟着的是http請求的正文,正文的內容是通過outputStream流寫入的, 
    實際上outputStream不是一個網絡流,充其量是個字符串流,往裏面寫入的東西不會立即發送到網絡, 
    而是存在於內存緩衝區中,待outputStream流關閉時,根據輸入的內容生成http正文。 
    至此,http請求的東西已經全部準備就緒。在getInputStream()函數調用的時候,就會把準備好的http請求 
    正式發送到服務器了,然後返回一個輸入流,用於讀取服務器對於此次http請求的返回信息。由於http 
    請求在getInputStream的時候已經發送出去了(包括http頭和正文),因此在getInputStream()函數 
    之後對connection對象進行設置(對http頭的信息進行修改)或者寫入outputStream(對正文進行修改) 
    都是沒有意義的了,執行這些操作會導致異常的發生。 

 

 

一般下載器

URL url = new URL(urlname);

HttpURLConnection con =(HttpURLConnection) url.openConnection();

con.setDoOutput(true);   

con.setDoInput(true);   

con.setUseCaches(false);  

con.setReadTimeout(2*60*1000);

//con.setRequestProperty("Content-type", "application/x-java-serialized-object");   

con.connect();

InputStream is = con.getInputStream();

 

BufferedReader br = new BufferedReader(new InputStreamReader(is));

StringBuffer sb = new StringBuffer();

String content ;

while((content=br.readLine())!=null){

//content = new String(content.getBytes(),"gbk");

sb.append(content);

}

 

(二)Apache接口

HttpClient:Http客戶端類(抽象類),可有DefaultHttpClient獲得

 

HttpGet/HttpPost:實現抓取網頁的信息

 

Execute():開始抓取網頁

 

HttpResponse類的getEntity()方法可獲取網頁內容

 

關於Post抓取網頁

需設置以下內容----設置字符集----設置實體

 

private void initHttpClient() {

HttpGet get = new HttpGet(httpUrl);//抓取http服務器上的信息

HttpClient client = new DefaultHttpClient();

HttpResponse response = client.execute(get);//執行抓取網頁信息,返回一個HttpResponse類的對象一測試是否抓取成功

if((response.getStatusLine().getStatusCode())==HttpStatus.SC_OK){

//抓取成功,可有抓取網頁成功後返回的HttpResponse對象獲取網頁內容

result = EntityUtils.toString(response.getEntity());//獲取網頁內容,返回的是Entity(實體類)類,

2.Android http請求設置網絡超時

HttpParams params = new BasicHttpParams();
        HttpConnectionParams . setConnectionTimeout ( params , 3000 ); 
    HttpConnectionParams . setSoTimeout ( params , 3000 );

HttpClient client = new DefaultHttpClient(params);

3.實例代碼

String weatherUrl = "http://113.108.239.107/data/"+cityCode+".html";

//設置超時

HttpParams params  =new BasicHttpParams();

HttpConnectionParams.setConnectionTimeout(params, 2*60*1000);

HttpConnectionParams.setSoTimeout(params, 2*60*1000);

HttpGet get = new HttpGet(weatherUrl);

HttpResponse response=null;

HttpClient client = new DefaultHttpClient(params);

try{

response = client.execute(get);

}catch(Exception e){

//出現連接超時等意外網絡情況則繼續5次

Log.e(tag, e.toString());

}

if(response!=null&&response.getStatusLine().getStatusCode()==HttpStatus.SC_OK){

try {

content = EntityUtils.toString(response.getEntity());

JSONParser(content);

catch (ParseException e) {

// TODO Auto-generated catch block

Log.e(tag, e.toString());

}finally{

}

}

else{

return false;

}

return true;

}

 

二、Socket通信

(一)Android接口

封裝了Http並有Socket---Wifi----Uri

主要類

(1).Socket----Wifi------Uri

(2).ExecutorService:

1.Socket

ServerSocket:服務器端

    ServerSocket server ;

    public void initServer() throws IOException{

        server = new ServerSocket(1034);//服務器端的特定端口(Port>1023

        Socket s = server.accept();//等待發出請求的客戶端的socket

        //獲取客戶的請求,即客戶所輸出的輸出流

        OutputStream os = s.getOutputStream();

        //變爲數據輸出流,篩選

        DataOutputStream dos = new DataOutputStream(os);

        dos.writeUTF("服務端已經收到消息");//向客戶端寫消息

注:此處只要獲取了客戶端的請求,再將輸出流變爲一個可寫流,調用write可向客戶端寫消息

        //接受客戶端信息

       InputStream is = s.getInputStream();

       BufferedReader dis = new BufferedReader(new InputStreamReader(is));

      //注:要接收客戶端消息必須要獲得服務端Socket的輸入流,相當於要在服務器端讀取客戶端的消息

        server.close();//關閉服務器

總結:服務器端要向客戶端接收,發送消息,必須與獲得的Socket對象建立起一個通信通道:即InputStreamOutputStream/可如此理解服務器要寫,所以要獲取客戶端的可寫入流,服務器要讀則要獲取客戶端的可讀入流其中的流可理解爲一個通道

 

Socket:客戶端

//向服務器請求並讀取服務器信息

Socket s = new Socket("118.124.6.164", 1034);//建立連接服務器的客戶端

//BufferedReader os = new BufferedReader(new InputStreamReader(s.getInputStream()));//獲取服務器信息

//result = os.readLine();

//showText.setText(result);

//向服務器寫信息

DataOutputStream dos = new DataOutputStream(s.getOutputStream());

dos.writeChars("client send message");

//PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(s.getOutputStream())), true);

s.close();

 

注:和服務器端一樣,要向服務器寫則需獲取客戶端Socket的可寫入流。要讀取服務器的消息則需要獲取客戶端Socket的可讀入流

 

注:客戶端和服務器端的輸入輸出要對應才行

 

2.實現多線程

ExecutorService:創建一個線程池

(1)獲取線程池

Executors類的newFixedThreadPool(2)可創建一個指定容量的線程池

 newCachedThreadPool()創建一個緩衝線程池

(2)執行線程:executeRunnable)參數爲一個Runnable對象

四.設置代理

1.HttpUrlConnetion

//當我們使用的是中國移動的手機網絡時,下面方法可以直接獲取得到10.0.0.17280端口

String host=android.net.Proxy.getDefaultHost();//通過andorid.net.Proxy可以獲取默認的代理地址

int port =android.net.Proxy.getDefaultPort();//通過andorid.net.Proxy可以獲取默認的代理端口

SocketAddress sa=new InetSocketAddress(host,port);

//定義代理,此處的Proxy是源自java.net

Proxy proxy=new Proxy(java.net.Proxy.Type.HTTP,sa);

URL getUrl = new URL(www.baidu.com); 

HttpURLConnection con = (HttpURLConnection) getUrl.openConnection(proxy);//設置代理

2.HttpClient

DefaultHttpClient httpClient=new DefaultHttpClient();

String host=Proxy.getDefaultHost();//此處Proxy源自android.net

int port = Proxy.getPort(context);//同上

HttpHost httpHost = new HttpHost(host, port); 

//設置代理

httpClient.getParams().setParameter(ConnRouteParams.DEFAULT_PROXY,httpHost);

HttpGet httpGet=new HttpPost("<a href="http://www.baidu.com">www.baidu.com</a>");

HttpResponse response=httpClient.execute(httpGet);

3.實例

DefaultHttpClient httpClient=new DefaultHttpClient();

//網絡檢測

ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);

if(cm!=null){

NetworkInfo  ni = cm.getActiveNetworkInfo();

if(ni!=null){

if(!ni.getTypeName().equals("WIFI")){

//設置代理

String host=Proxy.getDefaultHost();

int port = Proxy.getPort(context);  

HttpHost httpHost = new HttpHost(host, port); 

httpClient.getParams().setParameter(ConnRouteParams.DEFAULT_PROXY,httpHost);

}

}

}

五.常見問題

1.二級域名無法訪問

將域名換成ip

三.非阻塞IO

四.網絡編程前的準備

1.使用Chrome瀏覽器的Http頭分析插件分析HttpRequestResponse信息

Status

HTTP/1.1 200 OK

RequestAccept

text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8

Accept-Encoding

gzip,deflate,sdch

Accept-Language

zh-CN,zh;q=0.8,en;q=0.6

Cookie

lzstat_uv=32461900962640612022|3266776@2993663;
ASP.NET_SessionId=kuitmryyygrwt345l32mpj45

Referer

http://www.suse.edu.cn/

User-Agent

Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36

ResponseCache-Control

no-cache

Content-Encoding

gzip

Content-Length

10911

Content-Type

text/html; charset=utf-8

Date

Thu, 27 Mar 2014 12:16:47 GMT

Expires

-1

Pragma

no-cache,no-cache

Server

Microsoft-IIS/7.5

Vary

Accept-Encoding

X-AspNet-Version

2.0.50727

X-Powered-By

ASP.NET

2.不能獲取html網頁信息時的解決

使用con.setRequestProperty("User-Agent""Mozilla/5.0 (Linux; U; Android %s)");設置相關的http請求頭

五.網絡錯誤

1.不能連接到網站,總是出現連接超時

LogCat提示錯誤:

org.jsoup.HttpStatusException: HTTP error fetching URL. Status=404, URL=http://61.139.105.130:8080/zzxy/marks/index!list.action/?query=Java

解決辦法

查看所使用的url是否正確,如下

如果使用的Url是:http://rwxy.suse.edu.cn/images/Maincn.asp/

去掉最後的”/”反斜槓,http://rwxy.suse.edu.cn/images/Maincn.asp

設置相應的屬性

1)請求參數

2)User-Agent

3)Cookie

4)auth

JSoup.get().data("query","Java")//請求參數

.userAgent("Mozilla")//設置USER-AGENT

.cookie("auth""token")//設置cookie

2.不同網絡下的網絡訪問方式導致的錯誤

 

詳見

 

發佈了30 篇原創文章 · 獲贊 1 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章