計算機網路基礎-Socket

weixin_34290000發表於2018-04-03

1.Socket定義
socket即套接字,是應用層與TCP/IP協議族通訊的中間軟體抽象層,表現為一個封裝了TCP/IP協議族的程式設計介面(API)
1.1成對出現,一對套接字
Socket={(IP地址1:PORT埠號),(IP地址2:PORT埠號)}
一個Socket例項 唯一代表一個主機上的一個應用程式的通訊鏈路

2.建立Socket連線過程

客戶端
1.建立一個Socket例項
2.作業系統將為該Socket例項分配一個未被使用的本地埠號
3.作業系統建立一個含本地、遠端地址、埠號的套接字資料結構(系統將一直儲存該資料結構到連線關閉)
4.在建立Socket 例項的建構函式正確返回前,進行TCP的三次握手協議
5.TCP握手協議完成後,Socket例項物件將建立完成(否則將丟擲IOException錯誤)

伺服器
1.建立一個ServerSocket例項
2.作業系統將為該ServerSocket 例項差UN宮頸癌哪一個底層資料結構(含指定監聽的埠號、包含監聽地址的萬用字元、通常情況下是“*”,即監聽所有地址)
3.通過accept()方法時,將進入阻塞狀態、等待客戶端的請求
4.當一個新的請求到來時,將為該連線建立一個新的套接字資料結構(含請求源地址和介面並關聯到ServerSocket例項的一個未完成的連線資料結構列表中)
5.等三次握手完成後,該服務端的Socket例項才會返回&將該Socket例項對應的資料結構從未完成列表中移到已完成列表中(所以ServerSocket所關聯到的列表中每個資料結構,都代表與一個客戶端的建立TCP連線)

3.原理
Socket的使用型別主要有兩種:
流套接字(streamsocket) :基於 TCP協議,採用 流的方式 提供可靠的位元組流服務
資料包套接字(datagramsocket):基於 UDP協議,採用 資料包文 提供資料打包傳送的服務

4.Socket與Http對比
Socket屬於傳輸層,因為TCP/IP協議屬於傳輸層,解決的是資料如何在網路中傳輸的問題
Http協議屬於應用層,解決的事如何包裝資料
由於二者不屬於同一層面,所以本來是沒有可比性的,但隨著發展,預設的Http裡封裝了下面幾層的使用,所以才會出現Socket & HTTP協議的對比:(主要是工作方式的不同)
Http:採用請求-響應方式
1.即建立網路連線後,當客戶端向伺服器傳送請求後,伺服器端才能向客戶端返回資料
2.可理解為:是客戶端有需要才進行通訊
Socket:採用伺服器主動傳送資料的方式
1.即建立網路連線後,伺服器可主動傳送訊息給客戶端,而不需要由客戶端向伺服器傳送請求
2.可理解為:是伺服器端有需要才進行通訊

5.使用步驟
Socket可基於TCP或者UDP協議,但TCP更加常用
所以下面的使用步驟 & 例項的Socket將基於TCP協議

// 步驟1:建立客戶端 & 伺服器的連線
// 建立Socket物件 & 指定服務端的IP及埠號 
Socket socket = new Socket("192.168.1.232", 5060);  
// 判斷客戶端和伺服器是否連線成功  
socket.isConnected());
// 步驟2:客戶端 & 伺服器 通訊
// 通訊包括:客戶端 接收伺服器的資料 & 傳送資料 到 伺服器

<-- 操作1:接收伺服器的資料 -->
        // 步驟1:建立輸入流物件InputStream
        InputStream is = socket.getInputStream() 
        // 步驟2:建立輸入流讀取器物件 並傳入輸入流物件
        // 該物件作用:獲取伺服器返回的資料
        InputStreamReader isr = new InputStreamReader(is);
        BufferedReader br = new BufferedReader(isr);
        // 步驟3:通過輸入流讀取器物件 接收伺服器傳送過來的資料
        br.readLine();


<-- 操作2:傳送資料 到 伺服器 -->                  
        // 步驟1:從Socket 獲得輸出流物件OutputStream
        // 該物件作用:傳送資料
        OutputStream outputStream = socket.getOutputStream(); 
        // 步驟2:寫入需要傳送的資料到輸出流物件中
        outputStream.write(("Hello word"+"\n").getBytes("utf-8"));
        // 特別注意:資料的結尾加上換行符才可讓伺服器端的readline()停止阻塞
        // 步驟3:傳送資料到服務端 
        outputStream.flush();  


// 步驟3:斷開客戶端 & 伺服器 連線
         os.close();
        // 斷開 客戶端傳送到伺服器 的連線,即關閉輸出流物件OutputStream
        br.close();
        // 斷開 伺服器傳送到客戶端 的連線,即關閉輸入流讀取器物件BufferedReader
        socket.close();
        // 最終關閉整個Socket連線

相關文章