直播app原始碼中的資料傳輸的整個過程總結為四個詞就是建立、連線、傳送、斷開。每個互動過程都會進行詳細說明,耐心往下看哦。
互動過程如下圖所示:
套接字如何建立的
協議棧內部結構
如上圖所示,直播app原始碼的整個請求互動過程分為了幾個部分,首先最上層就是應用程式,接著往下是 Socket 庫
再下面就是作業系統的內部了,這裡面就包括了協議棧,協議棧上半部分為 TCP 和 UDP ,它們都是負責資料的收發,只是一個需要 連線,一個不需要連線可以直接收發資料。
協議棧的下半部分是 IP 協議,用來真正將直播app原始碼中的資料轉變為網路包進行實際資料傳送的媒介。
IP 下面就是網路卡驅動程式,用來控制網路卡硬體。
在直播app原始碼協議棧內部有一塊用來存放控制資訊的記憶體空間,這裡面記錄了需要連線的物件 IP 地址、埠號、進行狀態等資訊。
而套接字本身其實只是一個概念,實際並沒有這樣一個東西,這個概念如果非要賦予它一個實體,那控制資訊可以認為就是它的實體。
在直播app原始碼傳送資料時,我們需要看下套接字要進行連線的物件 IP 地址和埠號;傳送資料之後,套接字裡面會記錄傳送資料經過了多長時間,如果傳送收到響應,也會進行記錄。
我們來實際看下 套接字 都有哪些資訊,可以在你電腦的控制檯輸入 netstat 命令進行查詢:
- Proto: 表示協議型別。這裡是 tcp ,如果用到了 udp 就會顯示為 udp。
- Local Address : 本機的 IP 地址。
- Foreign Address : 通訊物件的 IP 地址
- state : 通訊狀態。ESTABLISHED 表示完成連線 ,CLOSE_WAIT
表示等待關閉,還有一個狀態也很常見,LISTENING:等待對方連線。
當瀏覽器通過 Socket 庫向協議棧發出 socket 呼叫時,協議棧就會根據申請執行建立套接字的操作。
協議棧首先會分配一個存放套接字的記憶體空間,然後往裡面存入控制資訊,這樣套接字就建立好了。
連線伺服器
建立好套接字後,瀏覽器會呼叫 connect ,協議棧就會將本地的套接字和伺服器的套接字進行連線。
連線就是直播app原始碼通訊雙方互相交換控制資訊,連線操作所交換的控制資訊是根據通訊規則來確定的,只要雙方根據規則進行連線,就能建立起連線關係,完成資料收發的準備。
控制資訊一般可以分為兩類,一類是直播app原始碼客戶端和伺服器相互聯絡時交換的控制資訊,這個資訊是兩者建立連線、資料收發、斷開連線整個通訊過程都需要的資訊,一般這些內容是通過 TCP 協議進行定義的。這些資訊會被新增進網路包的開頭,因此也叫作頭部,乙太網和 IP 協議也有自己的控制資訊,這個資訊也叫頭部,為了進行區分,我們分別叫作 TCP 頭部、乙太網頭部、IP 頭部。
這裡羅列了部分 TCP 頭部的資訊,僅供參考。
控制資訊還有一類,是儲存在套接字裡的,直播app原始碼傳遞的資訊和從通訊物件接受的資訊都會儲存在這裡,以及資料收發操作的執行狀態也會在這裡面。
連線操作的第一步就是在 TCP 模組處建立表示連線控制資訊的頭部。當 TCP 頭部建立好後,TCP 模組會將資訊傳遞給 IP 模組委託其進行傳送。IP 執行傳送後,網路包會通過網路到達直播app原始碼伺服器,伺服器上的 IP 模組將接收到的資料傳遞給 TCP 模組,TCP 模組根據頭部資訊找到對應的套接字,套接字中會寫入相應的資訊,然後將狀態改為正在連線。
於此同時,在返回響應時,會將 ACK 控制位設為 1,代表已接收到網路包。直播app原始碼伺服器 TCP 模組會將響應訊息通過 IP 模組向客戶端做出響應。
直播app原始碼客戶端接收到響應後,其 IP 模組將資訊傳遞給 TCP 模組,然後通過 TCP 頭部資訊確認連線是否成功,SYN 等於 1 就代表成功,客戶端還會將 ACK 設定為1 併發回給伺服器,伺服器收到這個包後才算連線操作真正的完成。
建立連線後,就可以隨時進行收發資料了,在呼叫 close 之前,連線會一直存在。
收發資料
收發資料的觸發操作是直播app原始碼發起的,通過調研 write,指定傳送資料的長度。
一般當協議棧接受到資料時可能並不會馬上發出去,而是放在傳送緩衝區中,為什麼要這樣做呢?
有些程式可能一次性會傳所有資料,但有些直播app原始碼會逐行傳遞,在這種情況下,如果收到資料就傳送,可能會造成傳送大量小包資料,導致效率低下。至於需要積累多少資料才傳送一般是根據兩方面因素來考量,一個是每個網路包的資料長度,還有一個緯度是處理時間。
- MTU: 一個網路包的最大長度,乙太網中一般是1500位元組,是包含頭部的總長度。
- MSS: 除去頭部後,一個網路包所有容納的資料最大長度。
當直播app原始碼傳送資料的頻率不高時,如果每次都需要等到長度達到 MSS 才傳送,就會造成等待時間過長。為了解決這種情況,協議棧會有一個計時器,如果達到一定時間,即使還遠未達到 MSS 長度,也會把網路包傳送出去。
當直播app原始碼客戶端向服務端傳送資料時,TCP會將資料的位元組數算好寫在 TCP 頭部,同時會生成一個隨機數 當作 ACK 一併傳送給服務端,服務端接受後就會根據實際收到的長度和TCP頭部給的長度做對比,來確保資料沒有遺漏,同時直播app原始碼客戶端還需要告知服務端是從哪個位元組開始傳送的,而我們的 ACK是個隨機值,這時候我們就需要通過 SYN 控制位設定為1傳送給伺服器,這樣伺服器就知道其初始是從哪個位元組開始傳送的。
接受方收到資料後,如果資料沒問題,就需要告知傳送方收到了多少資料,也是通過 ACK 號的操作來返回的,這個 ACK 的值就是一共接收了多少位元組。
通過這種機制,我們就可以確認接收方是否正確收到資料,如果沒有準確收到,就可以重新傳送網路包。
無論網路發生何種錯誤,我們就都可以發現並採取補救措施。
一般如果我們每傳送一個網路包就等待 ACK 返回確認後再傳送下一個包,這個等待 ACK 的時間啥都不做就會很浪費。
視窗滑動的概念就是直播app原始碼每次傳送一個網路包,不會等 ACK 返回就會繼續傳送下一個包,減少等待時間的浪費。
但這種方式也會存在問題,假如直播app原始碼傳送方不斷髮送資料給接收方,接收方第一個資料還沒處理完,第二個資料就來了,這些來不及處理的資料會進入接收緩衝區,資料會不斷增多,就會造成溢位。避免這種方式的處理是通過接收方告知傳送方自己最大能接收多少資料,傳送方會根據這個值對傳送的資料進行控制。
當我們資料收發完成後,就會啟動直播app原始碼的斷開機制,以 Web 為例,收發資料結束時,伺服器會發起斷開過程,會呼叫 Socket 庫的 close 程式,伺服器協議棧會生成一個包含斷開資訊的 TCP 頭部,就是將 FIN 位元設定為1。協議棧會委託 IP 模組向客戶端傳送資料。
當直播app原始碼客戶端接收到 FIN 為 1 的 TCP 頭部時,客戶端協議棧會將自己的套接字標記為進入斷開操作狀態,然後告知伺服器已經收到 FIN 為 1的包,客戶端會向伺服器返回一個 ACK 號。
UDP 協議收發操作
之前我們都是以 TCP 協議講解的資料收發操作,可以看出整個流程下來其實是挺複雜的,但是有時候可能我們並不需要這麼複雜的安全校驗,UDP 就可以滿足一些簡單的資料收發。例如像我們之前提到的 向 DNS 伺服器查詢 IP 地址,我們就是用的 UDP 協議。
UDP 沒有 TCP 的接收確認、視窗等機制,在收發資料之前是不需要進行交換控制資訊,不需要進行連線操作。
接收資料也很簡單,只需要根據 IP 頭部中的接收方和傳送方 IP 地址,以及 UDP 頭部中的接收方和傳送方埠號,找到對應的套接字然後將資料交給相應的直播app原始碼即可。
本文轉載自網路,轉載僅為分享乾貨知識,如有侵權歡迎聯絡雲豹科技進行刪除處理
原文連結:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69996194/viewspace-2848136/,如需轉載,請註明出處,否則將追究法律責任。