android網絡編程所涉及到的知識

Socket鏈接與HTTP鏈接 咱們在傳輸數據時,能夠只使用(傳輸層)TCP/IP協議,可是那樣的話,若是沒有應用層,便沒法識別數據內容,若是想要使傳輸的數據有意義,則必須使用到應用層協議,應用層協議有不少,好比HTTP、FTP、TELNET等,也能夠本身定義應用層協議。WEB使用HTTP協議做應用層協議,以封裝HTTP文本信息,而後使用TCP/IP作傳輸層協議將它發到網絡上。html

Socket是一個針對TCP和UDP編程的接口,你能夠藉助它創建TCP鏈接等等。而TCP和UDP協議屬於傳輸層 。 而http是個應用層的協議,它實際上也創建在TCP協議之上。java

(HTTP是轎車,提供了封裝或者顯示數據的具體形式;Socket是發動機,提供了網絡通訊的能力。)android

2)程序員

Socket是對TCP/IP協議的封裝,Socket自己並非協議,而是一個調用接口(API),經過Socket,咱們才能使用TCP/IP協議。Socket的出現只是使得程序員更方便地使用TCP/IP協議棧而已,是對TCP/IP協議的抽象,從而造成了咱們知道的一些最基本的函數接口。面試

下面是一些的重要的概念,特在此作摘抄和總結。spring

一。什麼是TCP鏈接的三次握手編程

第一次握手:客戶端發送syn包(syn=j)到服務器,並進入SYN_SEND狀態,等待服務器確認; 第二次握手:服務器收到syn包,必須確認客戶的SYN(ack=j+1),同時本身也發送一個SYN包(syn=k),即SYN+ACK包,此時服務器進入SYN_RECV狀態; 第三次握手:客戶端收到服務器的SYN+ACK包,向服務器發送確認包ACK(ack=k+1),此包發送完畢,客戶端和服務器進入ESTABLISHED狀態,完成三次握手。json

握手過程當中傳送的包裏不包含數據,三次握手完畢後,客戶端與服務器才正式開始傳送數據。理想狀態下,TCP鏈接一旦創建,在通訊雙方中的任何一方主動關閉鏈接以前,TCP 鏈接都將被一直保持下去。斷開鏈接時服務器和客戶端都可以主動發起斷開TCP鏈接的請求,斷開過程須要通過「四次握手」(過程就不細寫了,就是服務器和客戶端交互,最終肯定斷開)數組

二。利用Socket創建網絡鏈接的步驟瀏覽器

創建Socket鏈接至少須要一對套接字,其中一個運行於客戶端,稱爲ClientSocket ,另外一個運行於服務器端,稱爲ServerSocket 。

套接字之間的鏈接過程分爲三個步驟:服務器監聽,客戶端請求,鏈接確認。

1。服務器監聽:服務器端套接字並不定位具體的客戶端套接字,而是處於等待鏈接的狀態,實時監控網絡狀態,等待客戶端的鏈接請求。

2。客戶端請求:指客戶端的套接字提出鏈接請求,要鏈接的目標是服務器端的套接字。爲此,客戶端的套接字必須首先描述它要鏈接的服務器的套接字,指出服務器端套接字的地址和端口號,而後就向服務器端套接字提出鏈接請求。

3。鏈接確認:當服務器端套接字監聽到或者說接收到客戶端套接字的鏈接請求時,就響應客戶端套接字的請求,創建一個新的線程,把服務器端套接字的描述發給客戶端,一旦客戶端確認了此描述,雙方就正式創建鏈接。而服務器端套接字繼續處於監聽狀態,繼續接收其餘客戶端套接字的鏈接請求。

三。HTTP連接的特色

HTTP協議即超文本傳送協議(Hypertext Transfer Protocol ),是Web聯網的基礎,也是手機聯網經常使用的協議之一,HTTP協議是創建在TCP協議之上的一種應用。

HTTP鏈接最顯著的特色是客戶端發送的每次請求都須要服務器回送響應,在請求結束後,會主動釋放鏈接。從創建鏈接到關閉鏈接的過程稱爲「一次鏈接」。

四。TCP和UDP的區別

1。TCP是面向連接的,雖說網絡的不安全不穩定特性決定了多少次握手都不能保證鏈接的可靠性,但TCP的三次握手在最低限度上(實際上也很大程度上保證了)保證了鏈接的可靠性;而UDP不是面向鏈接的,UDP傳送數據前並不與對方創建鏈接,對接收到的數據也不發送確認信號,發送端不知道數據是否會正確接收,固然也不用重發,因此說UDP是無鏈接的、不可靠的一種數據傳輸協議。

2。也正因爲1所說的特色,使得UDP的開銷更小數據傳輸速率更高,由於沒必要進行收發數據的確認,因此UDP的實時性更好。

知道了TCP和UDP的區別,就不難理解爲什麼採用TCP傳輸協議的MSN比採用UDP的QQ傳輸文件慢了,但並不能說QQ的通訊是不安全的,由於程序員能夠手動對UDP的數據收發進行驗證,好比發送方對每一個數據包進行編號而後由接收方進行驗證啊什麼的,即便是這樣,UDP由於在底層協議的封裝上沒有采用相似TCP的「三次握手」而實現了TCP所沒法達到的傳輸效率。

JAVA中三種URL鏈接方法 Java的網絡類可讓你經過網絡或者遠程鏈接來實現應用。並且,這個平臺如今已經能夠對國際互聯網以及URL資源進行訪問了。Java的URL類可讓訪問網絡資源就像是訪問你本地的文件夾同樣方便快捷。咱們經過使用Java的URL類就能夠經由URL完成讀取和修改數據的操做。

經過一個URL鏈接,咱們就能夠肯定資源的位置,好比網絡文件、網絡頁面以及網絡應用程序等。其中包含了許多的語法元素。

  從URL獲得的數據能夠是多種多樣的,這些都須要一種統一的機制來完成對URL的讀取與修改操做。Java語言在它的java.net軟件包裏就提供了這麼一種機制。

URL class是從URL標示符中提取出來的。它容許Java程序設計人員打開某個特定URL鏈接,並對裏邊的數據進行讀寫操做以及對首部信息進行讀寫操做。並且,它還容許程序員完成其它的一些有關URL的操做。

  

構造

在建立java.net URL的實例的時候,你可以利用許多公共構造器,從而讓其變得更具靈活性。舉個例子來講,這個class提供了一種使用完整URL信息串的構造器,一種使用把URL信息串分解成爲協議、主機名以及文件和資源的構造器,還有一種把URL信息串分解成爲協議、主機名、端口號以及文件的構造器。咱們首先使用完整的URL來建立一個URL class的例子:

URL aURL = new URL(「http://www.mycompany.com:8080/index.html」);

在這個例子中,咱們建立了一個使用完整URL的URL class,其中明確指出了使用的協議是http,主機名稱是www.mycompany.com,端口號碼爲8080,文件/資源爲index.html。若是組成URL的語法發生了錯誤,那麼構造器就會發出MalformedURLException。

鏈接   一旦你成功的建立了一個URL class的實例,你就能夠對其進行操做了。可是在你可以訪問這個URL上的資源和內容以前,你必需要打開到這些資源與內容上的鏈接。你能夠經過使用openConnection來完成這一操做。

使用openConnection並不須要參數,而且在操做成功以後,它會返回一個URLConnection class的實例。在Listing A中,向咱們演示了打開一個到URL鏈接的過程。一旦你的鏈接成功,你就能夠開始對這個URLConnection的輸入以及輸出流進行讀和寫的操做了。

  從URL鏈接中讀取數據

使用java.io stream class來從URL中讀取數據是一個很是簡單的過程。一旦你創建了一個成功的鏈接,那麼你就能夠得到針對這個鏈接的輸入流而且開始進行寫的操做了。很幸運的是,java.io classes能夠以與對文件流或者socket流進行操做的一樣方式進行對從URLConnection流返回的數據進行操做。

  對URL進行寫的操做

使用java.io stream classes對URL進行寫的操做一樣也是很是簡單的。一旦你創建了一個成功的鏈接以後,你就能夠獲得來自此鏈接的輸出流而且開始進行寫的操做。固然,只有對於客戶所但願的數據進行寫的操做纔是有意義的。一樣的,在得到並對URLConnection流進行寫的操做以前,你還須要使用setDoOutput(boolean)方式把輸出(Output)屬性設置爲真(true)來指定能夠進行寫操做的那些鏈接。Java.io classes容許你把數據寫到URLConnection流,這個操做也和你對文件流和socket流進行的寫操做同樣。

  其它的操做

你能夠從URL以及URLConnection對象鏈接中獲得其它類型的信息,好比說主機名、端口、內容長度、內容編碼以及內容的類型。把這些方法連同stream I/O classes一塊兒使用可讓你創建複雜而有效的網絡客戶應用程序和服務。

  對網絡的便捷訪問

由Java平臺所提供的URL class讓咱們能夠方便而有效的訪問網絡上的資源,並且可讓咱們象訪問本地文件同樣的感到輕鬆愉快。咱們不用爲網絡通信的細節問題操心,只須要把注意力集中到製做有用的應用程序和服務上去。

三種鏈接方法

      // 方法一 
       URL url = new URL("http://www.sina.com.cn");
       URLConnection urlcon = url.openConnection();
       InputStream is = urlcon.getInputStream();
      
        // 方法二
       URL url = new URL("http://www.yhfund.com.cn");
       HttpURLConnection urlcon = (HttpURLConnection)url.openConnection();
       InputStream is = urlcon.getInputStream();
      
       //方法三
       URL url = new URL("http://www.yhfund.com.cn");
       InputStream is = url.openStream();
具體例子

       long begintime = System.currentTimeMillis();
      
       URL url = new URL("http://www.yhfund.com.cn");
       HttpURLConnection urlcon = (HttpURLConnection)url.openConnection();
       urlcon.connect();         //獲取鏈接
       InputStream is = urlcon.getInputStream();
       BufferedReader buffer = new BufferedReader(new InputStreamReader(is));
       StringBuffer bs = new StringBuffer();
       String l = null;
       while((l=buffer.readLine())!=null){
           bs.append(l).append("/n");
       }
       System.out.println(bs.toString());
      
       //System.out.println(" content-encode:"+urlcon.getContentEncoding());
       //System.out.println(" content-length:"+urlcon.getContentLength());
       //System.out.println(" content-type:"+urlcon.getContentType());
       //System.out.println(" date:"+urlcon.getDate());
            
       System.out.println("總共執行時間爲:"+(System.currentTimeMillis()-begintime)+"毫秒");
    }catch(IOException e){
       System.out.println(e);
   }
}

}

Java與Http協議 引言

http(超文本傳輸協議)是一個基於請求與響應模式的、無狀態的、應用層的協議,常基於TCP的鏈接方式。HTTP協議的主要特色是:
 1.支持客戶/服務器模式。
 2.簡單快速:客戶向服務器請求服務時,只需傳送請求方法和路徑。因爲HTTP協議簡單,通訊速度很快。
 3.靈活:HTTP容許傳輸任意類型的數據對象。類型由Content-Type加以標記。
 4.無鏈接:即每次鏈接只處理一個請求,處理完客戶的請求,並收到客戶的應答後,即斷開鏈接。採用這種方式能夠節省傳輸時間。
 5.無狀態:無狀態是指協議對於事務處理沒有記憶能力。 

 http1.0協議默認的是非持久鏈接, HTTP1.1默認的鏈接方式爲持久鏈接。

非持久鏈接:每次服務器發出一個對象後,相應的TCP鏈接就被關閉,也就是說每一個鏈接都沒有持續到可用於傳送其餘對象。每一個TCP鏈接只用於傳輸一個請求消息和一個響應消息。

持久鏈接:服務器在發出響應後讓TCP鏈接繼續打開着。同一對客戶/服務器之間的後續請求和響應能夠經過這個鏈接發送。HTTP/1.1的默認模式使用帶流水線的持久鏈接。

1、HTTP協議詳解之請求

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

//消息報頭 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表示請求方法(如POST、GET、PUT、DELETE等);Request-URI是一個統一資源標識符;HTTP-Version表示請求的HTTP協議版本;CRLF表示回車和換行。

2、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 //服務器當前不能處理客戶端的請求,一段時間後可能恢復正常

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

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

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

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

經常使用的請求報頭

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

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

二、響應報頭

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

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

  1. 實體報頭

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

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

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

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

4、補充

一、HTTP協議Content Lenth限制漏洞致使拒絕服務攻擊 使用POST方法時,能夠設置ContentLenth來定義須要傳送的數據長度,例如ContentLenth:999999999,在傳送完成前,內 存不會釋放,攻擊者能夠利用這個缺陷,連續向WEB服務器發送垃圾數據直至WEB服務器內存耗盡。這種攻擊方法基本不會留下痕跡。 二、爲了提升用戶使用瀏覽器時的性能,現代瀏覽器還支持併發的訪問方式,瀏覽一個網頁時同時創建多個鏈接,以迅速得到一個網頁上的多個圖標,這樣能更快速完成整個網頁的傳輸。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請求:GET與POST方法的區別   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爲好。

  五、Get是Form的默認方法。

Android網絡鏈接之HttpURLConnection和HttpClient 1.概念

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

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

2.區別

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

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

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";  
}

}
servlet端json轉化:

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();  
}

android之HttpURLConnection 1.HttpURLConnection鏈接URL 1)建立一個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();

Android消息推送 1.引言

  所謂的消息推送就是從服務器端向移動終端發送鏈接,傳輸必定的信息。好比一些新聞客戶端,每隔一段時間收到一條或者多條通知,這就是從服務器端傳來的推送消息;還好比經常使用的一些IM軟件如微信、GTalk等,都具備服務器推送功能。

  推送方法以下:

  1)經過SMS進行服務器端和客戶端的交流通訊。

  在Android平臺上,你能夠經過攔截SMS消息而且解析消息內容來了解服務器的意圖,能夠實現徹底的實時操做。可是問題是這個方案的成本相對比較高,且依賴於運營商。

  2)循環主動定時獲取

  這種方法須要客戶端來作一個定時或者週期性的訪問服務器端接口,以得到最新的消息。輪詢的頻率太慢可能致使某些消息的延遲,太快則會大量消耗網絡帶寬和電池。

  3)持久鏈接

  這個方案能夠解決由輪詢帶來的性能問題,可是仍是會消耗手機的電池。咱們須要開一個服務來保持和服務器端的持久鏈接(蘋果就和谷歌的C2DM是這種機制)。可是對於Android系統,當系統可用資源較低,系統會強制關閉咱們的服務或者是應用,這種狀況下鏈接會強制中斷。(Apple的推送服務之因此工做的很好,是由於每一臺手機僅僅保持一個與服務器之間的鏈接,事實上C2DM也是這麼工做的。即全部的推送服務都是經由一個代理服務器完成的,這種狀況下只須要和一臺服務器保持持久鏈接便可。C2DM=Cloud to Device Messaging)。

  相比之下第三種仍是最可行的。爲軟件編寫系統服務或開機啓動功能;或者若是系統資源較低,服務被關閉後能夠在onDestroy ()方法裏面再重啓該服務,進而實現持久鏈接的方式。

  C2DM內置於Android的2.2系統上,沒法兼容老的1.6到2.1系統;且依賴於Google官方提供的C2DM服務器,因爲國內的網絡環境,這個服務常常不可用。

  創建在TCP協議之上的XMPP協議,不只可提供可這種持久鏈接的功能,能實現服務器和客戶機的雙工通訊,還能不依賴與系統版本和google服務器的限制,提供了比較好的解決方案。

  1. XMPP協議

  XMPP全稱Extensible Messaging and Presence Protocol,前身是Jabber項目,是一種以XML爲基礎的開放式即時通信協議。XMPP由於被Google Talk和網易泡泡應用而被廣大網民所接觸。XMPP的關鍵特點是,分散式的即時通信系統,以及使用XML串流。XMPP目前被IETF國際標準組織完成了標準化工做。

  Android push notification(androidpn) 是一個基於XMPP協議的java開源實現,它包含了完整的客戶端和服務器端。該服務器端基本是在另一個開源工程openfire基礎上修改實現的。

  androidpn客戶端須要用到一個基於java的開源XMPP協議包asmack,這個包一樣也是基於openfire下的另一個開源項目smack,不過咱們不須要本身編譯,能夠直接把androidpn客戶端裏面的asmack.jar拿來使用。客戶端利用asmack中提供的XMPPConnection類與服務器創建持久鏈接,並經過該鏈接進行用戶註冊和登陸認證,一樣也是經過這條鏈接,接收服務器發送的通知。

  androidpn服務器端也是java語言實現的,基於openfire開源工程,不過它的Web部分採用的是spring框架,這一點與openfire是不一樣的。Androidpn服務器包含兩個部分,一個是偵聽在5222端口上的XMPP服務,負責與客戶端的XMPPConnection類進行通訊,做用是用戶註冊和身份認證,併發送推送通知消息。另一部分是Web服務器,採用一個輕量級的HTTP服務器,負責接收用戶的Web請求。服務器的這兩方式,意義非凡:當相應的TCP端口被防火牆封閉,可使用輪詢的方式進行訪問,所以又有助於經過防火牆。

相關文章
相關標籤/搜索