1. 程式人生 > >Android網路程式設計基礎(一)

Android網路程式設計基礎(一)

前言

最近專案上用到了網路通訊相關的很多技術,越做越發現自己之前接觸的實在是太少了,要學的太多,所以儘量每週末總結一篇Android網路通訊相關的部落格,先從網路程式設計基礎開始,包含基於TCP/IP或者UDP的Socket基礎、HTTP程式設計,然後是一些網路模組程式設計,比如地圖、Wifi、藍芽、NFC等等,本類文章注重於技術的使用和實用,對底層程式碼不涉及太深入。在整個過程中,我會不斷優化自己的程式設計框架和嘗試更多的新技術,慢慢的讓自己對框架理解的更加透徹,順便完成自己的一個大的專案。對網路通訊感興趣的朋友,可以隨時加我qq,一起學習~

推薦書籍

  • 《瘋狂Java講義》 第17章 網路程式設計
  • 《瘋狂Android講義》 第13章 Android網路應用
  • 《Android網路程式設計:技術詳解與最佳實踐》
  • 《深入理解Android:WiFi模組 NFC和GPS卷》
  • 百度百科:有問題百度一下~

基礎知識

如果僅僅針對Android開發,不需要了解太多的計算機網路相關的知識,但是知道一些基本的東西,對我們深入學習Android網路程式設計有很大的幫助~小編表示,大學學的計算機網路已經還給了老師,強烈要求退學費( ̄▽ ̄)”

1.計算機網路概述

計算機網路就是用物理鏈路將各個孤立的工作站或主機連線在一起, 組成資料鏈路,從而達到資源共享和通訊的目的。凡將地理位置不同且具有獨立功能的多個計算機系統通過通訊裝置和線路連線起來, 並以功能完善的網路軟體( 網路協議、 資訊交換方式及網路作業系統等) 實現網路資源共享的系統, 均可稱為計算機網路。 簡單地說, 計算機網路即連線兩臺或多臺計算機進行通訊的系統。

2.OSI參考模型和TCP/IP模型

國際標準化組織( ISO) 在 1978 年提出了“開放系統互連參考模型”, 即著名的 OSI/RM 模型( Open System Interconnection/Reference Model)。 OSI 是標準化組織為了實現裝置互聯而提出的一個純理論的框架性的概念。也可就是說:它只能告訴我們一個網路應該具備哪些功能,某個功能的實現是在某個層次,但具體的實現技術他是不進行規範的。因為OSI的網路模型標準比較嚴格,另外推出的時間也相對較晚,所以目前還沒有完全按照OSI模型實現的網路。TCP/IP是另一種網路模型,也是我們實際應用最廣泛的一種網路的模型。

在這個模型中,不只是劃分了功能層,還有具體的實現技術,即協議。TCP和IP就是這個模型中最重要的兩個層次的代表協議。這兩個模型之間的可以說是完全獨立的。因為OSI是一種理論上的指導。而TCP/IP是一種事實上的標準。但兩者也是有一定聯絡的,兩者都是網路模型,都存在某些相同的層次。另外,OSI是一個通用性的指導,它不僅可以解釋TCP/IP,還可以解釋任何一種型別的網路。而TCP/IP是無法解釋其他網路的。

這裡寫圖片描述

我們重點關注一下TCP/IP模型中的傳輸層和網路層的協議即可:

這裡寫圖片描述

  • TCP:傳輸控制協議,它規定了一種可靠的資料傳輸,經常和網路層的IP協議合併使用,統稱為TCP/IP協議。

  • UDP:使用者資料報協議,一種無連線的傳輸層協議,提供面向事務的簡單不可靠資訊傳送服務。有不提供資料包分組、組裝和不能對資料包進行排序的缺點,也就是說,當報文傳送之後,是無法得知其是否安全完整到達的。

    簡單對比

TCP UDP
可靠性 面向連線,可靠性好
效率 資源消耗較高,效率較低

3.IP地址和埠號

在網路程式設計中一定要掌握IP地址和埠號知識,IP地址用於唯一的標識網路中的一個通訊實體,這個通訊實體既可以是一臺主機,也可以是一臺印表機,或者是路由器的某一個埠。在基於IP協議網路中傳輸的資料包,都必須使用IP地址來進行標識。

IP地址的劃分:

這裡寫圖片描述

在這五類ip地址中,我們需要重點關注的是:

  • 私有IP地址:

    在現在的網路中,IP地址分為公網IP地址和私有IP地址。公網IP是在Internet使用的IP地址,而私有IP地址則是在區域網中使用的IP地址。也就是說私有IP地址只能在區域網中使用,比如你向主機位192.168.0.1這個主機發訊息,傳送不到公網去,區域網會主動在區域網內查詢該主機。

類別 範圍
A類IP地址中的私有地址 10.0.0.0到10.255.255.255
B類IP地址中的私有地址 172.16.0.0到172.31.255.255
C類IP地址中的私有地址 192.168.0.0到192.168.255.255

- 組播IP地址:就是D類IP地址。

範圍 作用
224.0.0.0~224.0.0.255 預留的組播地址(永久組地址)
224.0.1.0~224.0.1.255 公用組播地址,可以用於Internet
224.0.2.0~238.255.255.255 使用者可用的組播地址(臨時組地址),全網範圍內有效
239.0.0.0~239.255.255.255 本地管理組播地址,僅在特定的本地範圍內有效

稍後,我們會重點學習一下單播、組播和多播的知識。

4.埠號

IP地址用於唯一的標識網路上的一個通訊實體,但是一個通訊實體可以有多個通訊程式同時提供網路服務,此時需要使用埠號。埠是一個16位的整數,用於表示資料交給哪個通訊程式處理,因此,埠就是應用程式與外界交流的出入口,它是一種抽象的軟體結構,包括一些資料結構和I/O緩衝區。

不要的應用程式處理不同的埠號,同一臺機器上不能有兩個程式使用同一個埠,埠號分為:

範圍 作用
公認埠 0~1023
註冊埠 1024~49151
動態或私有埠 49152~65535

簡單講,IP地址就是你的家庭住址,具體到街道和門牌號,埠就相當於你的房間號碼。當一個程式需要傳送資料的時候,需要指定目的地的IP地址和埠號。

5.單播、組播、廣播

簡單區分一下:

  • 單播:一對一,傳送者和接收者建立點對點網路連線,進行通訊。

    ​ 優點:伺服器及時響應客戶端的請求,針對每個客戶端實現不同的響應。

    ​ 缺點:在流媒體應用中因為資料流過大,伺服器會不堪重負。

  • 廣播:一對多,向某個網段傳送資訊,該網段內的所有主機都會收到資訊。

    ​ 優點:網路裝置簡單,成本低,伺服器流量負載低;

    ​ 缺點:無法針對每個客戶端的要求實現不同的響應,並且容易造成資訊氾濫,最關鍵的是禁止在公網傳播,只能在區域網內使用。

  • 組播:一對組,傳送端傳送一次資料,加入同一個組播組的所有主機都可以接收到這份資料。

    簡單講,

    單播:就是單聊,一對一通訊;

    廣播:就是群發,你傳送的訊息所有人都會收到;

    組播:就是群聊,你發的訊息在這個群裡的所有人都會收到。

Android基本網路支援

1.獲取網路基本資訊

Java中,該類表示IP地址,並且還有兩個子類Inet4Address和Inet6Address分別代表IPv4和IPv6地址。該類沒有構造方法,通過以下兩個靜態方法來獲取InetAddress例項:

  • getByName(String host):根據主機名獲取對應的InetAddress物件;
  • getByAddress(byte[] addr):根據原始IP地址來獲取對應的InteAddress物件;
  • getLocalHost():獲取本機IP地址對應的InetAddress類;

還有如下三個方法來獲取該例項對應的IP地址和主機名:

  • String getCanonicalHostName():獲取此IP地址的全限定域名;
  • String getHostName():獲取此IP地址的主機名;
  • String getHostAddress():返回該InetAddress例項對應的IP地址字串;
  • isReachable():用於測試該IP地址是否可以達到;

程式碼:

這裡寫圖片描述

列印結果:

這裡寫圖片描述

結果分析:對於手機來講,其實通過InetAddress獲取的本機IP並沒有什麼卵用,都是127.0.0.1代表本機,如果是電腦的話會獲取到電腦的區域網ip。所以,手機要通過WifiManage來獲取WifiInfo,然後所有的資訊都可以通過該類獲取:

  • int getIpAddress():獲取區域網分配的IP地址;

    IP地址是32位,返回的是int型別,四個位元組,所以需要稍微解析一下,變成字串表示的形式:

    /** 將Ip地址改成字串表示格式 */
    public static String IntToIp(int i) {
    LogUtil.i("【CommonUtil】", "IntToIp");
    return (i & 0xFF) + "." +
      ((i >> 8) & 0xFF) + "." +
      ((i >> 16) & 0xFF) + "." +
      (i >> 24 & 0xFF);
    }
  • int getNetworkId():獲取網路ID;

  • String getSSID():獲取SSID;

2.Socket相關

資料包的長度是有限的,傳輸的時候需要將其分解為多個包, 在到達傳輸的目的地址後再組合還原。 如包有丟失或
者破壞需要重傳時, 則亂序傳送的包在達到時需要重新排序。 處理這些過程是一項繁雜的工作, 需要大量可靠的程式碼來完成。 為了使程式設計師不必費心於上述這些底層具體細節, 通過 Socket 對網路糾錯、 包大小、 包重傳等進行了封裝。

Socket的英文原義是“孔”或“插座”,通常也稱作”套接字”,用於描述IP地址和埠,是一個通訊鏈的控制代碼,可以用來實現不同虛擬機器或不同計算機之間的通訊。在Internet上的主機一般運行了多個服務軟體,同時提供幾種服務。每種服務都開啟一個Socket,並繫結到一個埠上,不同的埠對應於不同的服務。客戶軟體將插頭插到不同編號的插座,就可以得到不同的服務。

Socket通訊模型:

這裡寫圖片描述

3.TCP通訊模型

這裡寫圖片描述

4.UDP通訊模型

這裡寫圖片描述

後面會詳細介紹Android通訊程式設計中,這幾種模型的開發,以及實戰。