通過一些問題來討論 TCP 協議
- 什么是 TCP ?舉幾個應用了 TCP 協議的例子
- TCP協議如何保證可靠性?
- tcp如何保證不會接受重復的報文?
- Tcp粘包拆包問題了解嗎?介紹一下,如何解決?
- TCP擁塞控制與流量控制區別?
- 現在我們視頻面試用到哪些協議
1.?什么是 TCP ?舉幾個應用了 TCP 協議的例子
TCP 就是連接控制協議,是面向連接的,可靠的,基于字節流的傳輸層通信協議。
其中面向連接一定是一對一的連接。可靠性指無論網絡鏈路中出現了什么狀況,TCP 都會盡力保證一個報文能夠無損壞,無冗余,按序到達。基于字節流是指用戶消息通過 TCP 協議傳輸時,會被操作系統分組成多個 TCP 報文,并且這些報文之間是有序的
像我們平時用到的最多的網頁中的 HTTP 協議,傳輸層協議就是 TCP。類似用到 TCP 的應用層還有 FTP 文件傳輸協議,SMTP 簡單郵件傳輸協議和 SSH,它們的傳輸層都需要 TCP 來做可靠性保證
2.?TCP協議如何保證可靠性?
首先 TCP 每次建立連接都需要三次握手,釋放連接需要四次揮手來確保建立的傳輸通道是可靠的
其次,TCP 采用了連續 ARQ 協議來保證數據傳輸的正確性,同時還使用了滑動窗口機制來控制發送方的發送速率,保證接收方一定能接受到發送的數據,也就是流量控制機制
還有,TCP 利用序列號和校驗和,來分別確保數據傳輸的有序性和完整性
最后在整個網絡層面上,TCP 還使用慢啟動,擁塞避免,快速重傳和快速恢復來進行擁塞控制,避免網絡阻塞帶來的數據接好問題
3.?tcp如何保證不會接受重復的報文?
這個是由 TCP 報文中的“序列號”字段保證的,TCP 在建立連接時,客戶端和服務端都會將一個內核生成的隨機數作為自己的初始序列號。在建立連接完成后,開始發送數據時,發送的一端會將“上次發送的序列號”加上“上次發送的數據長度”作為“本次報文的序列號”發送給對端。對端在收到數據包時,會根據序列號來確定接收到數據的順序和是否重復,如果重復收到某個序列號的報文,則只會接收一次,其他的都丟棄
需要注意的是,在三次握手和四次揮手階段,發送端序列號的值就不是“上次發送的序列號”加上“上次發送的數據長度”的值,而是“上次發送的序列號”加上 “1”
還有,序列號除了確保數據接收的“有序性”,還有用于 TCP 的流量控制中。具體的,TCP 連接的兩端都會維護一個發送窗口和接受窗口。發送方根據 TCP 報文的序列號和發送窗口的大小來確定可以發送的數據量。接收方使用序列號和接收窗口大小來確定可以接收的數據量,并通知發送方來控制發送速率,以此來確保雙方數據都能夠被順利接收。
4.?Tcp粘包拆包問題了解嗎?介紹一下,如何解決?
首先 TCP 是處在傳輸層的面向流的協議的協議,它本身不會按照應用開發者的期望,保持每次發送時都帶有一個數據的邊界,這可能導致接收端一次收到了多個應用層報文,需要應用開發者自己分開,也就是需要自己去實現“流”到“數據報”的功能。具體的解決,可以用“特殊字符作為邊界”,也就是我們對于應用層的每個信息后面都加上一些特殊字符用來代表信息結束。當讀到了這些特殊字符,就意味著已經讀完了一個完整的消息。比如 HTTP 通過設置回車符和一個換行符來作為 HTTP 報文協議的邊界。但需要注意的是,如果信息內容中剛好出現了這些字符,可能會導致信息提前結束和數據錯亂,這時我們可以對這些個字符進行轉義,避免這種情況。
其實還有一種“粘包”的含義:就是 TCP 在實現的時候,為了解決大量小報文場景下,包頭比數據還大,導致傳輸的性價比太低的情況,采用了一種叫 Nagle 的算法。這個算法的效果就是將開發者多次發送的小數據,粘在同一個 TCP 報文中發出。這樣可能就會導致先被發送的數據可能需要等待一段時間,才能跟后面才被發送的數據一起組成報文發送出去。但在實際中這種算法帶來的延遲幾乎可以忽略不計,絕大多數情況都是無感知的。只有在頻繁進行超短信息的交互,比如只有幾個字節的場景,禁用 Nagle 算法才能顯著降低延遲。
5.?TCP擁塞控制與流量控制區別?
兩者誕生的原因就不同:
需要流量控制的原因是,端到端在通信時,發送方的速率與接收方的速率不一致,如果發送方發的速率太快,會導致接收方處理不過來;而如果發送方發送的太慢,數據就會有一定的延遲。那么此時就需要通過一種方法來控制發送方的速率,這個方法就叫“流量控制”
而擁塞控制不同于流量控制,它主要強調的是網絡的擁塞,導致發送方發的數據包被堵在了半路,而接收方遲遲沒收到數據包并返回接收到的最后一個包的確認報文,會讓發送方誤以為這個包丟了并重新發送,這不僅會浪費信道資源,還會使原來擁塞的網絡雪上加霜。
6.?現在我們視頻面試用到哪些協議
考慮到視頻時對于延遲很敏感,所以應該具有 UDP 傳輸速度快的特性,但又能允許一定程度的丟包。但又不能丟包率太高,還應具備 TCP 有關數據傳輸可靠性的保證,確保不會視頻著視頻著突然畫面就沒有了的情況。所以我覺得應該是同時結合了 TCP 可靠性和 UDP 速度快的優點,這類協議我了解的是谷歌提出的 QUIC 協議。
QUIC 協議全稱是“快速 UDP 互聯網”連接,相比與當前應用多的 http2 + tcp + tls,它的優勢主要在減少了 TCP 三次握手以及 TLS 握手的時間,擁有改進后的擁塞控制,以及擁有避免隊頭阻塞的多路復用。
首先由于 UDP 本身沒有連接的概念,不需要三次握手,QUIC 在此基礎上實現了 0 RTT 的安全握手,并且在大部分情況下也只需 0 RTT 就能實現數據發送。
為了保證可靠性傳輸,QUIC 在 TCP 關于擁塞控制方面的四個算法,包括慢啟動,擁塞避免,快速重傳,快速回復都做了相應的改進。比較突出的特點就是,QUIC 使用 packet number 代替了 TCP 的 sequence number,且每個 packet number 都嚴格遞增。加上同樣是 QUIC 提出的 Stream Offset,確保數據的順序性和可靠性。
除此之外,QUIC 還在 Connection 和 Stream 兩個級別都提供了流量控制。Stream 可以理解為一條 http 請求,Connection 可以類比一條 TCP 連接。QUIC 的多路復用就是指在一條 Connection 上同時存在多條 Stream,且多條 Stream 之間沒有順序依賴,也就消除了 TCP 中隊頭阻塞的問題。
大致只了解這么多。
誠懇歡迎大家提出意見
......(待續未完