兩個進程進行通訊最基本的前提是能唯一標識一個進程,在本地進程通訊中可以使用 PID 來唯一標識一個進程,但 PID 在本地是唯一的,網絡中兩個進程 PID 衝突機率很大,這就要通過其他手段來唯一標識進程了,IP 層的 ip 地址可以唯一標示主機,再結合 TCP 端口號就可以唯一標示某個主機的進程。
唯一標示網絡中的進程後,就可以利用 Socket 通信了,到底什麼是 Socket 呢?我們經常把 Socket 翻譯為套接字,Socket 是在應用層和傳輸層之間的一個抽象層,它把 TCP/IP 層複雜的操作抽象為幾個簡單的接口供應用層調用,從而實現進程在網絡中通信。
Socket 編程,可以基於 TCP 或 UDP 實現,Java 為 Socket 編程封裝了幾個重要的類,我們來認識一下:
Socket (TCP)
Socket 類實現了一個客戶端 Socket,作為兩臺機器通信的終端,默認採用的傳輸層協議為可靠的 TCP 傳輸協議,主要方法如下:
connect() 用於請求一個 socket 連接
getOutputStream 用於獲得寫 socket 的輸出流
getInputStream 用於獲得讀 socket 的輸入流
close 用於關閉一個流。
DatagramSocket (UDP)
DatagramSocket 類實現了一個發送和接收數據報的 socket,傳輸層協議使用 UDP,不能保證數據報的可靠傳輸,主要方法如下:
send 用於發送一個數據報,Java 提供了 DatagramPacket 對象用來表達一個數據報
receive 用於接收一個數據報,調用該方法後,一直阻塞接收到直到數據報或者超時
close 關閉一個 socket。
ServerSocket
ServerSocket 類實現了一個服務端 socket,服務端 socket 等待客戶端網絡請求,然後基於這些請求執行操作,並返回給請求者結果,主要方法如下:
bind 方法為 ServerSocket 綁定一個 IP 地址和端口,並開始監聽該端口
accept 方法為 ServerSocket 接受請求並返回一個 Socket 對象,accept 方法調用後,將一直阻塞直到有請求到達
close 方法關閉一個 ServerSocket 對象。
SocketAddress
SocketAddress 提供了一個 socket 地址,不關心傳輸層協議。這是一個虛類,由子類來具體實現功能、綁定傳輸協議。它提供了一個不可變的對象,被 socket 用來綁定、連接或者返回數值。
InetSocketAddress
InetSocketAddress 實現了 IP 地址的 SocketAddress,也就是有 IP 地址和端口號表達 Socket 地址。如果不制定具體的 IP 地址和端口號,那麼 IP 地址默認為本機地址,端口號隨機選擇一個。
DatagramPacket(UDP)
DatagramPacket 表示一個數據包,需要與 DatagramSocket 配合使用才能完成基於數據報的 socket 通信。
代碼示例
來看一個簡單的 TCP 通信示例,加深對 Socket 編程的瞭解。
服務端
服務端通過 ServerSocket 實現一個 socket,等待客戶端請求:
當 accept 到請求後,啟動了一個子線程去處理,處理前先要初始化 IO 流:
在任務中接收處理客戶端發來的信息,我們假定 “0” 表示客戶端主動請求斷開:
客戶端
客戶端知道服務端 IP 地址及端口號後,通過 Socket 請求建立連接:
發送和接收數據跟服務端一樣,分別通過 PrintWriter 和 BufferedReader 來實現。至此,客戶端和服務端就能愉快的進行全雙工通信了。
最後附一張圖來總結:
轉載請超鏈接註明:頭條資訊 » Android 基於 TCP的Socket 編程實現
免責聲明 :非本網註明原創的信息,皆為程序自動獲取互聯網,目的在於傳遞更多信息,並不代表本網贊同其觀點和對其真實性負責;如此頁面有侵犯到您的權益,請給站長發送郵件,並提供相關證明(版權證明、身份證正反面、侵權鏈接),站長將在收到郵件24小時內刪除。