Android - 基於TCP和UDP Socket通訊講解

前言

許多專案都使用網路通訊協議傳送資料,除了與網站後端通訊之外,裝置與裝置之間的網路通訊也非常重要,所以網絡協議是必須掌握的知識,TCP/IP 中最具代表性的傳輸層協議分別為 TCP 與 UDP,根據不同專案的功能需求使用TCP或UDP通訊協定,同時,跨平台與手機App進行互動,本文介紹TCP和UDP相關基礎知識,並提供Android TCP及UDP 簡易聊天室的開發範例。

淺談TCP、UDP

「傳輸控制協定」(Transmission Control Protocol,TCP) 是一種具有可連接性及可靠性的位於傳輸層的位元組傳輸協定,由「網際網路工程任務小組」(Internet Engineer Task Force;IETF)的RFC793制定說明,在開放式系統互聯模型(英語:Open System Interconnection Model,縮寫:OSI;簡稱為OSI模型)為第四層傳輸層的協定,在傳輸資料內加入驗證碼,當對方收到後,依據此驗證碼,回傳對應的確認訊息,發送端再繼續下一筆資料封包的傳送,若對方未及時傳回確認訊息,封包就重新發送一次,以確保資料傳輸的完整性,為了確保每一個封包都可在目的端依照順序接受到,在每一個位元組前給一個序號(ISN),且每一筆封包都會進行Check Sum確保資料的正確性及完整性。

「使用者資料流協定」( User Datagram Protocol,UDP) 是屬於一種非可靠性的非連線導向傳輸協定,與TCP同樣屬於OSI第四層傳輸層的協定,負責網路層到應用層間的傳輸功能,而UDP跟TCP不同的地方,UDP只提供資料的不可靠傳遞,當封包發送出去,並不保留資料備份,所以傳輸過程中掉封包並不會有重新傳送封包的動作,且UDP不需大量的欄位,相較於TCP的負載少,適用於一些資料量大、具時效性及資料正確性要求較低的應用。

TCP與UDP介紹與比較表


範例製作:簡易聊天室

範例為實作一個客戶端和伺服器的簡易聊天系統,訊息的傳送和接收是基於TCP協議。

程式碼通訊流程如下圖:



Manifest權限設定:

android.permission.INTERNET
android.permission.ACCESS_WIFI_STATE

 

Android TCP函式介紹

ServerSocket:

  • ServerSocket(int port):建構監聽指定Port,Port範圍介於1024~65535,其中0~1023為系統保留不可使用,建構時必須注意,避免發生衝突。
  • accept():客戶端的Socket未發出連線請求,伺服器就會一直等待,直到客戶端發送連線請求,請求成功後返回一個與客戶端對應的服務端Socket,如果設置Timeout時間,當伺服器等待的時間超過了超時時間,就會拋出異常SocketTimeoutException。
  • setSoTimeout:設置accept()超實時間,以毫秒為單位。
  • isClosed():查詢連接是否已關閉。
  • close():關閉此ServerSocket。 

Socket:

  • Socket(String host, int port) :建構一個串流,連接到指定的主機位置及指定Port。
  • isConnected():是否連線。
  • getInputStream():取得Socket輸入流,用於接收送過來的資料。
  • getOutputStream():取得Socket輸出流,發送資料。
  • getInetAddress().getHostAddress():取得客戶端的IP位置。

 

Android TCP Server端

建立ServerSocket,並執行accept(),這裡執行緒會阻塞等待Client端連線,當連線完成後輸出Socket,透過Socket將getInputStream及getOutputStream建立,如此即可完成送收資料流,資料接收端則使用While迴圈判斷reader.readLine()的資料是否為Null,若是則跳開。




TCP Client端

建立Socket連接指定IP及Port,判斷是否連線,若連線成功則在螢幕顯示“Connected”, 並透過Socket將getInputStream及getOutputStream建立,如此即可完成送收資訊流,資料接收端則使用While迴圈判斷reader.readLine()的資料是否為Null,若是則跳開。


TCP簡易聊天室執行畫面
圖左為Server伺服器端,圖右為Client客戶端。

  






接下來實現一個簡易聊天系統,訊息的傳送和接收是基於UDP協議,使用者不需要輸入IP,但需要對應指定Port(範例設定為8085)做發送與接收。

Android UDP函式介紹

DatagramSocket:

  • DatagramSocket():綁定到本地主機上任何可用的端口。
  • DatagramSocket(int port):綁定到本機IP位置及指定埠。
  • DatagramSocket(int port, InetAddress laddr):綁定到指定IP位置及指定埠。
  • receive(DatagramPacket p):接收資料封包。
  • send(DatagramPacket p):發送資料封包。

DatagramPacket

  • DatagramPacket(byte[] buf,int length):建構DatagramPacket,負責接收長度為length的數據封包。
  • DatagramPacket(byte[] buf, int length, InetAddress addr, int port):建構DatagramPacket,發送資料長度為length至指定IP位置和指定Port。

 

UDP完成數據的接收

由於UDP無明顯的Server端與Client端,一開始執行程式直接開啟接收執行緒,建立DatagramSocket監聽Port,範例Port設定為8085,並且使用While迴圈內包含DatagramPacket接收UDP廣播封包資料,並將資料顯示於畫面中。

 


UDP完成數據的發送

建立DatagramSocket用於發送DatagramPacket封包,DatagramPacket建立設定封包、封包長度、IP、指定Port(範例設定為8085),DatagramPacket建立完成後透過DatagramSocket發送廣播封包。



UDP簡易聊天室執行畫面



小結

開發相關產品時,需要清楚自身需求選用適合的通訊協議,TCP連接只能是點到點,並提供安全可靠服務,通過TCP傳送數據,不丟包、不重複,且按序到達,應用於瀏覽器使用HTTP、Outlook使用POP/SMTP、指令傳輸及文件傳輸。UDP支持一對一,一對多,多對一和多對多的交互通信,通過UDP傳送數據,不安全、會丟包及重複數據,應用於語音通話、多媒體及網路視訊等。

 

GitHub程式網址:https://github.com/s801210/AndroidTcpUdpDemo.git

 

參考資料

維基百科:傳輸控制協定(TCP)

https://zh.wikipedia.org/wiki/%E4%BC%A0%E8%BE%93%E6%8E%A7%E5%88%B6%E5%8D%8F%E8%AE%AE

維基百科:用戶資料報協定(UDP)

https://zh.wikipedia.org/wiki/%E7%94%A8%E6%88%B7%E6%95%B0%E6%8D%AE%E6%8A%A5%E5%8D%8F%E8%AE%AE

維基百科:TCP/UDP埠列表

https://zh.wikipedia.org/wiki/TCP/UDP%E7%AB%AF%E5%8F%A3%E5%88%97%E8%A1%A8

Android 開發人員 Docs:Socket

https://developer.android.com/reference/java/net/Socket

相關影片

Android - 基於TCP和UDP Socket通訊講解

Android - 基於TCP和UDP Socket通訊講解

★博文內容均由個人提供,與平台無關,如有違法或侵權,請與網站管理員聯繫。

★文明上網,請理性發言。內容一周內被舉報5次,發文人進小黑屋喔~

參考來源

評論