計算機網路 簡單聊聊套接字 Socket

2021-09-25 10:44:10 字數 2442 閱讀 3360

socket 由來:

在學習乙個新知識之前,要去想它為什麼會出現,它的出現解決了什麼問題.這樣印象才會深刻一些.

在同乙個主機下,兩個程序間的通訊是很容易,直接把各種通訊細節交給作業系統去做就 ok 了.但是如果兩個程序是處於不同主機下呢?該如何進行通訊呢?而且在實際的應用場景中,是很複雜的,有的使用 tcp 協議,有的使用 udp 協議,那麼當我們使用不同的協議進行通訊時,是不是就要使用不同的介面?同時還要處理不同協議的各種通訊細節,這樣一來,是不是就增加了開發的難度,同時軟體不容易進行擴充套件.

程式設計思想之一就是「物件導向」,同樣,在遇到這種問題時,我能不能把不同協議的通訊細節抽出來,這樣程式設計師在使用的時候,直接呼叫,就不需要再關注協議本身了.而這就是 socket 的由來.

它提供介面,來進行互聯的不同主機之間的程序通訊.你想要讓不同主機之間通訊? ok ,你直接呼叫我就行,至於我怎麼實現,程式設計師不需要 care .

在上面的基礎上,我們能夠達成乙個共識:如果乙個應用,需要在客戶端和服務端之間進行通訊,那就需要建立乙個 socket 例項.

那麼問題來了,我如何使用?

socket 進行的是端到端的通訊,中間經過多少區域網,路過多少路由器,我是不清晰的,所以能夠設定的引數,也只是端到端協議之上的網路層和傳輸層.

在網路層, socket 函式需要指定使用到的協議到底是 ipv4 還是 ipv6 ,分別對應設定為 af_inet 和 af_inet6 .此外,還需要說明你是使用 tcp 協議,還是 udp 協議. tcp 協議是基於資料流的,所以設定為 sock_stream , udp 是基於資料報的,因而設定為 sock_dgram .

基於 tcp 協議的 socket 程式函式呼叫過程

客戶端和服務端建立 socket 之後, tcp 的服務端要先監聽乙個埠,一般是先呼叫 bind 函式,給這個 socket 賦予乙個 ip 位址和埠.為什麼需要 ip 位址呢?有時候一台機器會有多個網絡卡,相應的就會有多個 ip 位址,可以選擇監聽所有的網絡卡,也可以選擇監聽乙個網絡卡,這樣只有發給這個網絡卡的包,才會給你.那我為什麼還需要埠呢?你要知道,你寫的是乙個應用程式,當乙個網路包來的時候,核心是需要通過 tcp 頭裡面的這個埠,來定位到你這個應用程式的.

此時,當服務端有了 ip 和埠號,就可以呼叫 listen 函式進行監聽.在 tcp 的狀態圖中,有乙個 listen 狀態,當呼叫這個函式之後,服務端就進入了這個狀態,這個時候客戶端那邊就可以發起連線了.

在核心中,為每個 socket 維護了兩個佇列,乙個是已經建立了連線的佇列,說明此時三次握手已經完畢,處於 established 狀態;乙個是還沒有完全建立連線的佇列,也就是說這個時候三次握手還沒完成,處於 syn_rcvd 的狀態.

接下來,服務端呼叫 accept 函式,拿出乙個已經完成的連線進行處理.如果客戶端還沒有完全建立連線,沒別的辦法,就等著咯.

在服務端等待的時候,客戶端可以通過 connect 函式發起連線.現在引數中指明要連線的 ip 位址和埠號,然後開始發起三次握手.核心會給客戶端分配乙個臨時的埠,一旦握手成功,服務端的 accept 就會返回另乙個 socket .

注意一下,在這裡有乙個經常考察的知識點,就是監聽的 socket 和真正用來傳資料的 socket 是兩個,乙個叫做「監聽 socket 」,乙個叫做「已連線 socket 」.

連線建立成功之後,雙方就開始通過 read 和 write 函式來讀寫資料,就像往乙個檔案流裡面寫東西一樣.之所以把 tcp 的 socket 描述成乙個檔案流,是因為 socket 在 linux 中就是以檔案的形式存在的.

在核心中, socket 是乙個檔案,那對應就有檔案描述符.每乙個程序都有乙個資料結構 task_struct ,裡面指向乙個檔案描述符陣列,來列出這個程序開啟的所有檔案的檔案描述符.檔案描述符是乙個整數,是這個陣列的下標.

這個陣列中的內容是乙個指標,指向核心中所有開啟的檔案的列表.既然是乙個檔案,就會有乙個 inode ,只不過 socket 對應的 inode 不像真正的檔案系統一樣,儲存在硬碟上,而是在記憶體中.在這個 inode 中,指向了 socket 在核心中的 socket 結構.

在這個結構中,主要的是兩個佇列,乙個是傳送佇列,乙個是接收佇列.在這兩個佇列裡面儲存的是乙個快取 sk_buff .這個快取中能夠看到完整的包的結構.

以上,就是基於 tcp 協議的 socket 程式函式呼叫過程的乙個描述.

接下來說說基於 udp 協議的 socket 程式函式呼叫過程.

基於 udp 協議的 socket 程式函式呼叫過程

對於 udp 來說,和 tcp 還是有些不一樣的.首先, udp 是沒有連線的,也就不需要三次握手,也不需要呼叫 listen 和 connect ,但是 udp 的互動仍然需要 ip 和埠號,那就需要 bind .

udp 是沒有維護連線狀態的,也就不需要對每對連線建立一組 socket ,而是只要有乙個 socket 就可以和多個客戶端通訊.也是因為沒有連線狀態,所以每次通訊的時候,都呼叫 sendto 和 recvfrom ,這樣才可以傳入 ip 位址和埠.

計算機網路 簡單聊聊套接字 Socket

socket 由來 在學習乙個新知識之前,要去想它為什麼會出現,它的出現解決了什麼問題.這樣印象才會深刻一些.在同乙個主機下,兩個程序間的通訊是很容易,直接把各種通訊細節交給作業系統去做就 ok 了.但是如果兩個程序是處於不同主機下呢?該如何進行通訊呢?而且在實際的應用場景中,是很複雜的,有的使用 ...

計算機網路之套接字SOCKET

當某個應用程序啟動系統呼叫時,控制權就從應用程序傳遞給了系統呼叫介面。此介面再將控制權傳遞給計算機的作業系統。作業系統將此呼叫轉給某個內部過程,並執行所請求的操作。內部過程一旦執行完畢,控制權就又通過系統呼叫介面返回給應用程序。關於tcp ip協議最著名的api就是berkeleyunix 作業系統...

計算機網路實驗 UDP套接字程式設計

我用自己的ubuntu16.04來舉例,實驗室的是虛擬機器,差不多 只針對第三個題目,修改伺服器來通過響應客戶端傳送的gettime並傳送給客戶端當前系統時間。ubuntu16.04介面就不說了。我只是多下了chrome,藍燈和uget 建立檔案敲 不知道你自己會把 放在 所以這一步自己注意。沒有 ...