前言
許多專案都使用網路通訊協議傳送資料,除了與網站後端通訊之外,裝置與裝置之間的網路通訊也非常重要,所以網絡協議是必須掌握的知識,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
評論