4.2 網絡通訊

  • 網絡基礎協議

   

TPC/IP協議是傳輸層協議,主要解決數據如何在網絡中傳輸。java

HTTP是應用層協議,主要解決如何包裝數據。程序員

  關於TCP/IP和HTTP協議的關係,網絡有一段比較容易理解的介紹:「咱們在傳輸數據時,能夠只使用(傳輸層)TCP/IP協議,可是那樣的話,若是沒有應用層,便沒法識別數據內容,若是想要使傳輸的數據有意義,則必須使用到應用層協議,應用層協議有不少,好比HTTP、FTP、TELNET等,也能夠本身定義應用層協議。WEB使用HTTP協議做應用層協議,以封裝HTTP文本信息,而後使用TCP/IP作傳輸層協議將它發到網絡上。」web

 TCP創建鏈接和斷開鏈接的過程簡析:chrome

   

  創建鏈接:首先Client端發送鏈接請求報文,Server段接受鏈接後回覆ACK報文,併爲此次鏈接分配資源。Client端接收到ACK報文後也向Server段發生ACK報文,並分配資源,這樣TCP鏈接就創建了。apache

  中斷鏈接:能夠是Client端,也能夠是Server端。假設Client端發起中斷鏈接請求,也就是發送FIN報文。Server端接到FIN報文後,意思是說"我Client端沒有數據要發給你了",可是若是你還有數據沒有發送完成,則沒必要急着關閉Socket,能夠繼續發送數據。因此你先發送ACK,"告訴Client端,你的請求我收到了,可是我還沒準備好,請繼續你等個人消息"。這個時候Client端就進入FIN_WAIT狀態,繼續等待Server端的FIN報文。當Server端肯定數據已發送完成,則向Client端發送FIN報文,"告訴Client端,好了,我這邊數據發完了,準備好關閉鏈接了"。Client端收到FIN報文後,"就知道能夠關閉鏈接了,可是他仍是不相信網絡,怕Server端不知道要關閉,因此發送ACK後進入TIME_WAIT狀態,若是Server端沒有收到ACK則能夠重傳。「,Server端收到ACK後,"就知道能夠斷開鏈接了"。Client端等待了2MSL後依然沒有收到回覆,則證實Server端已正常關閉,那好,我Client端也能夠關閉鏈接了。Ok!編程

  •  Android中幾種網絡通訊的手段

 1)針對TCP/IPSocketServerSocket瀏覽器

TCP/IP是一種面向鏈接的、可靠的協議。Socket僅僅是對TCP、UDP網絡接口的封裝,不涉及上層協議。TCP、UDP傳輸特性不一樣,分別適用於不一樣類型的應用層協議,其中TCP有鏈接,延時較長,能保證服務質量;UDP無鏈接,須要應用程序進行數據分包、延時短,效率高,數據包可能丟失或到達對端發生順序混亂。在Socket之上能夠實現這些RFC標準的應用層協議,也能夠自定義實現私有的應用層協議。服務器

2)針對UDPDatagramSocketDatagramPackage網絡

  這裏須要注意的是,考慮到Android設備一般是手持終端,IP都是隨着上網進行分配的。不是固定的。所以開發也是有一點與普通互聯網應用有所差別的。異步

  1. 對於UDP服務端,首先啓動偵聽服務,而後獲得數據包進行處理,組後根據得到數據包進行反饋。
  2. UDP socket沒有鏈接的概念,所以構造完成的DatagramSocket不會發出向對端的網絡鏈接請求,在每個發送的UDP數據包中包含目的地址和端口。由於UDP數據不會在對端進行從新組包,所以一次發送的數據長度必須加以限制

 3)針對直接URLHttpURLConnection

  apache httpclient高效穩定,可是維護成本高昂,故Android 開發團隊不肯意在維護該庫而是轉投更爲輕便的httpurlconnection;httpurlconnection比較輕便,靈活和易於擴展。

  HttpURLConnection的connect()函數,實際上只是創建了一個與服務器的tcp鏈接,並無實際發送http請求。不管是post仍是get,http請求實際上直到HttpURLConnection的getInputStream()這個函數裏面才正式發送出去。

  在用POST方式發送URL請求時,URL請求參數的設定順序是重中之重,對connection對象的一切配置(那一堆set函數)都必需要在connect()函數執行以前完成。而對outputStream的寫操做,又必需要在inputStream的讀操做以前。 這些順序其實是由http請求的格式決定的。若是inputStream讀操做在outputStream的寫操做以前,會拋出: java.net.ProtocolException: Cannot write output after reading input.......

  http請求實際上由兩部分組成, 一個是http,全部關於這次http請求的配置都在http頭裏面定義, 一個是正文content。connect()函數會根據HttpURLConnection對象的配置值生成http頭部信息,所以在調用connect函數以前,就必須把全部的配置準備好。在http頭後面緊跟着的是http請求的正文,正文的內容是經過outputStream流寫入的,實際上outputStream不是一個網絡流,充其量是個字符串流,往裏面寫入的東西不會當即發送到網絡,而是存在於內存緩衝區中,待outputStream流關閉時,根據輸入的內容生成http正文至此,http請求的東西已經所有準備就緒。

  在getInputStream()函數調用的時候,就會把準備好的http請求正式發送到服務器了,而後返回一個輸入流,用於讀取服務器對於這次http請求的返回信息。因爲http請求在getInputStream的時候已經發送出去了(包括http頭和正文),所以在getInputStream()函數以後對connection對象進行設置(對http頭的信息進行修改)或者寫入outputStream(對正文進行修改)都是沒有意義的了,執行這些操做會致使異常的發生。

4使用Web Service。Android能夠經過開源包如jackson去支持Xmlrpc和Jsonrpc,另外也能夠用Ksoap2去實現Webservice 。它是一種基於SAOP協議的遠程調用標準,經過webservice能夠將不一樣操做系統平臺,不一樣語言,不一樣技術整合到一塊兒。在Android中,第三方公司提供了基於webservice的jar包。

(5)直接使用WebView視圖組件顯示網頁。基於WebView 進行開發,Google已經提供了一個基於chrome-lite的Web瀏覽器,直接就能夠進行上網瀏覽網頁。

理解Socket

  實際上socket是對TCP/IP協議的封裝,Socket自己並非協議,而是一個調用接口(API),經過Socket,咱們才能使用TCP/IP協議。實際上,Socket跟TCP/IP協議沒有必然的聯繫。Socket編程接口在設計的時候,就但願也能適應其餘的網絡協議。因此說,Socket的出現只是使得程序員更方便地使用TCP/IP協議棧而已,是對TCP/IP協議的抽象,從而造成了咱們知道的一些最基本的函數接口,好比create、listen、connect、accept、send、read和write等等。網絡有一段關於socket和TCP/IP協議關係的說法比較容易理 解:「TCP/IP只是一個協議棧,就像操做系統的運行機制同樣,必需要具體實現,同時也要提供可供程序員作網絡開發所用的接口,這就是Socket編程接口。」

理解斷點續傳

斷點續傳是HTTP 1.1協議的一部分,並不須要客戶端特地去作多麼複雜的事情。

只要利用了HTTP協議中的以下字段來和服務器端交互,就能夠實現文件下載的斷點續傳:

Range:用於客戶端到服務器端的請求,可經過該字段指定下載文件的某一段大小,及其單位。典型的格式如:

  • Range: bytes=0-499      下載第0-499字節範圍的內容
  • Range: bytes=500-999  下載第500-999字節範圍的內容
  • Range: bytes=-500       下載最後500字節的內容
  • Range: bytes=500-       下載從第500字節開始到文件結束部分的內容(這是最經常使用的一種格式)
  • Range: bytes=0-0,-1     下載第一以及最後一個字節的內容(這個看上去有點變態...)

Accept-Ranges:用於服務器端到客戶端的應答,客戶端經過該字段能夠判斷服務器是否支持斷點續傳(可選字段)。格式以下:Accept-Ranges: bytes  //表示支持以bytes爲單位進行傳輸;  如果 none  表示不支持

Content-Ranges:用於服務器端到客戶端的應答,與Accept-Ranges在同一個報文內,經過該字段指定了返回的文件資源的字節範圍。格式以下:

  • Content-Ranges: bytes 0-499/1234             大小爲1234的文件的第0-499字節範圍的內容
  • Content-Ranges: bytes 734-1233/1234        大小爲1234字節的文件的第734-結尾範圍的內容

據此咱們能夠知道,斷點續傳這個功能是須要客戶端和服務器端同時支持才能完成

  Android平臺面向開發者提供了DownloadManager這個服務(service),能夠用來完成下載,同時異步地獲得下載進度的實時更新提示。該接口也部分的提供了斷點續傳功能:若是在下載過程當中遇到網絡錯誤,如信號中斷等,DownloadManager會在網絡恢復時嘗試斷點續傳繼續下載該文件。但不支持由用戶發起的暫停而後斷點續傳。要擴展該功能也不難,只要爲下載任務新增一種狀態(相似paused_by_user),以及相關邏輯便可。

【附】服務端和客戶端交互使用了兩種方式:XML、JSON

相關文章
相關標籤/搜索