0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

TCP和UDP的區(qū)別

科技綠洲 ? 來源:Linux開發(fā)架構(gòu)之路 ? 作者:Linux開發(fā)架構(gòu)之路 ? 2023-11-09 09:35 ? 次閱讀

1.TCP和UDP的區(qū)別

TCP是面向連接的,UDP是面向無連接的;

TCP只能一對一通信,UDP支持一對一,一對多,多對一和多對多交互通信;

TCP是面向字節(jié)流的,UDP是面向報(bào)文的;

TCP是可靠傳輸,使用流量控制和擁塞控制;UDP是不可靠傳輸

TCP首部最小20字節(jié),最大60字節(jié);UDP首部僅8字節(jié)。

2.ISO七層模型及相關(guān)協(xié)議

物理層:建立、維護(hù)、斷開物理連接。

數(shù)據(jù)鏈路層:在物理層提供比特流服務(wù)的基礎(chǔ)上,建立相鄰結(jié)點(diǎn)之間的數(shù)據(jù)鏈路。

網(wǎng)絡(luò)層:進(jìn)行邏輯地址尋址,實(shí)現(xiàn)不同網(wǎng)絡(luò)之間的路徑選擇,協(xié)議有ICMP、IGMP、IP等。

傳輸層:定義傳輸數(shù)據(jù)的協(xié)議端口號,以及流量控制和差錯校驗(yàn),協(xié)議有TCP、UDP。

會話層:建立、管理、終止會話,指本地主機(jī)與遠(yuǎn)程主機(jī)正在進(jìn)行的會話。

表示層:確保一個系統(tǒng)的應(yīng)用層所發(fā)送的信息可以被另一個系統(tǒng)的應(yīng)用層讀取。

應(yīng)用層:網(wǎng)絡(luò)服務(wù)與最終用戶的一個接口,常見的協(xié)議有:HTTP、FTP、SMTP、DNS。

TCP/IP 四層模型

  1. 網(wǎng)絡(luò)接口層
  2. 網(wǎng)際層
  3. 傳輸層
  4. 應(yīng)用層

五層體系結(jié)構(gòu)

  1. 物理層
  2. 數(shù)據(jù)鏈路層
  3. 網(wǎng)絡(luò)層:IP網(wǎng)際協(xié)議、ARP地址轉(zhuǎn)換協(xié)議、RIP路由信息協(xié)議
  4. 傳輸層:TCP傳輸控制協(xié)議、UDP用戶數(shù)據(jù)報(bào)文協(xié)議
  5. 應(yīng)用層:HTTP超文本傳輸協(xié)議、FTP文本傳輸協(xié)議、DNS域名系統(tǒng)

3.如何理解HTTP協(xié)議是無狀態(tài)的

當(dāng)瀏覽器第一次發(fā)送請求給服務(wù)器時,服務(wù)器響應(yīng)了;

如果同個瀏覽器發(fā)起第二次請求給服務(wù)器時,它還是會響應(yīng)。但是呢,服務(wù)器不知道你就是剛才的那個瀏覽器。

簡而言之,服務(wù)器不會去記住你是誰,所以是無狀態(tài)協(xié)議。

4.簡述從瀏覽器地址欄輸入url到顯示主頁的過程

  1. DNS解析,查找域名對應(yīng)的IP地址。
  2. 與服務(wù)器通過三次握手,建立TCP連接。
  3. 向服務(wù)器發(fā)送HTTP請求。
  4. 服務(wù)器處理請求,返回網(wǎng)頁內(nèi)容。
  5. 瀏覽器解析并渲染頁面。
  6. TCP四次握手,連接結(jié)束。

圖片

5.說下 HTTP/1.0,1.1,2.0 的區(qū)別

HTTP/1.0

默認(rèn)使用短連接,每次請求都需要建立一個TCP連接。它可以設(shè)置Connection: keep-alive 這個字段,強(qiáng)制開啟長連接。

HTTP/1.1

  1. 默認(rèn)使用長連接,即TCP連接默認(rèn)不關(guān)閉,可以被多個請求復(fù)用。
  2. 分塊傳輸編碼,即服務(wù)端每產(chǎn)生一塊數(shù)據(jù),就發(fā)送一塊,用“流模式”取代“緩存模式”。
  3. 管道機(jī)制,即在同一個TCP連接里面,客戶端可以同時發(fā)送多個請求。

HTTP/2.0

  1. 二進(jìn)制協(xié)議,1.1版本的頭信息是文本(ASCII編碼),數(shù)據(jù)體可以是文本或二進(jìn)制;2.0中,頭信息和數(shù)據(jù)體都是二進(jìn)制。
  2. 完全多路復(fù)用,在一個連接里,客戶端和服務(wù)器都可以同時發(fā)送多個請求或響應(yīng),而且不用按照順序一一對應(yīng)。
  3. 報(bào)頭壓縮,HTTP協(xié)議不帶有狀態(tài),每次請求都必須帶上所有信息。HTTP/2.0引入了頭信息壓縮機(jī)制,使用gzip或compress壓縮后再發(fā)送。
  4. 服務(wù)端推送,允許服務(wù)器未經(jīng)請求,主動向客戶端發(fā)送資源。

6.POST和GET有哪些區(qū)別

圖片

7.HTTP 如何實(shí)現(xiàn)長連接?在什么時候會超時?

什么是HTTP的長連接?

  1. HTTP分為長連接和短連接,本質(zhì)上說的是TCP的長短連接。TCP連接是一個雙向的通道,它是可以保持一段時間不關(guān)閉的,因此TCP連接才具有真正的長連接和短連接這一說法。
  2. TCP長連接可以復(fù)用一個TCP連接,來發(fā)起多次HTTP請求,這樣就可以減少資源消耗,比如一次HTML請求,如果是短連接的話,可能還需要請求后續(xù)的JS/CSS。

如何設(shè)置長連接?

通過在請求頭和響應(yīng)頭設(shè)置Connection字段指定為keep-alive,HTTP/1.0協(xié)議支持,但默認(rèn)是關(guān)閉的,從HTTP/1.1以后,連接默認(rèn)都是長連接。

在什么時候會超時?

  1. HTTP一般會有httpd守護(hù)進(jìn)程,里面可以設(shè)置keep-alive timeout,當(dāng)tcp連接閑置超過這個時間就會關(guān)閉,也可以在HTTP的header里面設(shè)置超時時間。
  2. TCP 的keep-alive包含三個參數(shù),支持在系統(tǒng)內(nèi)核的net.ipv4里面設(shè)置;當(dāng) TCP 連接之后,閑置了tcp_keepalive_time,則會發(fā)生偵測包,如果沒有收到對方的ACK,那么會每隔 tcp_keepalive_intvl 再發(fā)一次,直到發(fā)送了tcp_keepalive_probes,就會丟棄該連接。
tcp_keepalive_intvl = 15
tcp_keepalive_probes = 5
tcp_keepalive_time = 1800

8.HTTP 與 HTTPS 的區(qū)別

HTTP 即超文本傳輸協(xié)議,是一個基于TCP/IP通信協(xié)議來傳遞明文數(shù)據(jù)的協(xié)議。HTTP會存在這幾個問題:

  • 請求信息是明文傳輸,容易被竊聽截取。
  • 沒有驗(yàn)證對方身份,存在被冒充的風(fēng)險(xiǎn)。
  • 數(shù)據(jù)的完整性未校驗(yàn),容易被中間人篡改。

為了解決HTTP存在的問題,HTTPS出現(xiàn)啦。

HTTPS是什么?

HTTPS= HTTP+SSL/TLS,可以理解為 HTTPS 是身披 SSL(Secure Socket Layer,安全套接層)的HTTP。

它們的主要區(qū)別如下:

圖片

9.HTTPS的工作流程是怎樣的?

  • HTTPS = HTTP + SSL/TLS,也就是用SSL/TLS對數(shù)據(jù)進(jìn)行加密和解密,用HTTP進(jìn)行傳輸。
  • SSL,即Secure Sockets Layer(安全套接層協(xié)議),是網(wǎng)絡(luò)通信提供安全及數(shù)據(jù)完整性的一種安全協(xié)議。
  • TLS,即Transport Layer Security(安全傳輸層協(xié)議),它是SSL3.0的后續(xù)版本。

圖片

  1. 客戶端發(fā)起HTTPS請求,連接到服務(wù)器的443端口。
  2. 服務(wù)器必須要有一套數(shù)字證書(證書內(nèi)容有公鑰、證書頒發(fā)機(jī)構(gòu)、失效日期等)。
  3. 服務(wù)器將自己的數(shù)字證書發(fā)送給客戶端(公鑰在證書里面,私鑰由服務(wù)器持有)。
  4. 客戶端收到數(shù)字證書之后,會驗(yàn)證證書的合法性。如果證書驗(yàn)證通過,就會生成一個隨機(jī)的對稱密鑰,用證書的公鑰加密。
  5. 客戶端將公鑰加密后的密鑰發(fā)送到服務(wù)器。
  6. 服務(wù)器接收到客戶端發(fā)來的密文密鑰之后,用自己之前保留的私鑰對其進(jìn)行非對稱解密,解密之后就得到客戶端的密鑰,然后用客戶端密鑰對返回?cái)?shù)據(jù)進(jìn)行對稱加密,這樣子傳輸?shù)臄?shù)據(jù)都是密文啦。
  7. 服務(wù)器將加密后的密文返回到客戶端。
  8. 客戶端收到后,用自己的密鑰對其進(jìn)行對稱解密,就能得到服務(wù)器返回的數(shù)據(jù)。

10.說說HTTP的狀態(tài)碼,301和302的區(qū)別?

  • 301:永久重定向,表示所請求的資源已經(jīng)永久地轉(zhuǎn)移到新的位置,這包含域名的改變或者是資源路徑的改變。
  • 302:臨時重定向,表示所請求的資源臨時地轉(zhuǎn)移到新的位置,一般是24到48小時以內(nèi)的轉(zhuǎn)移會用到302。

11.說說什么是數(shù)字簽名?什么是數(shù)字證書?

圖片

數(shù)字證書構(gòu)成:

  • 公鑰和個人等信息,經(jīng)過Hash算法加密,形成消息摘要;將消息摘要拿到擁有公信力的認(rèn)證中心(CA),用它的私鑰對消息摘要加密,形成數(shù)字簽名。
  • 公鑰和個人信息、數(shù)字簽名共同構(gòu)成數(shù)字證書。

12.對稱加密和非對稱加密有什么區(qū)別

對稱加密:指加密和解密使用同一密鑰,優(yōu)點(diǎn)是運(yùn)算速度較快,缺點(diǎn)是不能安全地將密鑰傳輸給另一方。常見的對稱加密算法有:DES、AES等。

圖片

非對稱加密:指的是加密和解密使用不同的密鑰(即公鑰和私鑰)。公鑰與私鑰是成對存在的,如果用公鑰對數(shù)據(jù)進(jìn)行加密,只有對應(yīng)的私鑰才能解密。常見的非對稱加密算法有 RSA。

圖片

13.說說 DNS 的解析過程?

DNS的解析過程如下圖:

圖片

假設(shè)你要查詢www.baidu.com的IP地址:瀏覽器 -> 本地DNS服務(wù)器 -> 根域名服務(wù)器 -> 頂級域名服務(wù)器 -> 權(quán)威域名服務(wù)器

  1. 首先會查找瀏覽器的緩存,看看是否能找到www.baidu.com對應(yīng)的IP地址,找到就直接返回;否則進(jìn)行下一步。
  2. 將請求發(fā)往本地DNS服務(wù)器,如果查找到也直接返回,否則繼續(xù)進(jìn)行下一步;
  3. 本地DNS服務(wù)器向根域名服務(wù)器發(fā)送請求,根域名服務(wù)器返回負(fù)責(zé).com的頂級域名服務(wù)器的列表。
  4. 本地DNS服務(wù)器再向其中一個頂級域名服務(wù)器發(fā)送一個請求,返回負(fù)責(zé).baidu的權(quán)威域名服務(wù)器的列表。
  5. 本地DNS服務(wù)器再向其中一個權(quán)威域名服務(wù)器發(fā)送一個請求,返回www.baidu.com所對應(yīng)的IP地址。

14.說說 WebSocket與socket的區(qū)別

Socket是一套標(biāo)準(zhǔn),它完成了對TCP/IP的高度封裝,屏蔽網(wǎng)絡(luò)細(xì)節(jié),以便開發(fā)者更好地進(jìn)行網(wǎng)絡(luò)編程

Socket等于IP地址 + 端口 + 協(xié)議。

WebSocket是一個持久化的協(xié)議,它是伴隨H5而出的協(xié)議,用來解決HTTP不支持持久化連接的問題。

Socket是一個網(wǎng)絡(luò)編程的標(biāo)準(zhǔn)接口,而WebSocket則是應(yīng)用層通信協(xié)議。

15.HTTP請求的過程與原理

HTTP是一個基于TCP/IP協(xié)議來傳遞數(shù)據(jù)的超文本傳輸協(xié)議,傳輸?shù)臄?shù)據(jù)類型有HTML、圖片等。

圖片

  1. 客戶端進(jìn)行DNS域名解析,得到對應(yīng)的IP地址
  2. 根據(jù)這個IP地址,找到對應(yīng)的服務(wù)器建立TCP連接(三次握手)
  3. 建立TCP連接后發(fā)起HTTP請求(一個完整的http請求報(bào)文)
  4. 服務(wù)器響應(yīng)HTTP請求,客戶端得到html代碼
  5. 客戶端解析html代碼,用html代碼中的資源(如 js、css、圖片等等)渲染頁面。
  6. 服務(wù)器關(guān)閉TCP連接(四次揮手)

16.forward和redirect的區(qū)別?

是servlet中的兩種主要跳轉(zhuǎn)方式。forward:轉(zhuǎn)發(fā),redirect:重定向

從地址欄顯示來說

forward是服務(wù)器內(nèi)部的重定向,服務(wù)器直接訪問目標(biāo)地址,把里面的東西取出來,但是客戶端并不知道,因此用forward的話,客戶端瀏覽器的網(wǎng)址是不會發(fā)生變化的。

redirect是服務(wù)器根據(jù)邏輯,發(fā)送一個狀態(tài)碼,告訴瀏覽器重新去請求那個地址,所以地址欄顯示的是新地址。

從數(shù)據(jù)共享來說

由于在整個轉(zhuǎn)發(fā)的過程中使用的是同一個request,因此forward會將request信息帶到被重定向的jsp或servlet中使用,即可以共享數(shù)據(jù)。

redirect不能共享數(shù)據(jù)。

從運(yùn)用的地方來說

forward一般用于用戶登錄時,根據(jù)角色轉(zhuǎn)發(fā)到相應(yīng)的模塊

redirect一般用于用戶注銷登錄時返回主頁面

從本質(zhì)上來說

forward轉(zhuǎn)發(fā)是服務(wù)器上的行為,redirect重定向是客戶端的行為。

從效率上來說

forword效率高,而redirect效率低。

從請求的次數(shù)來說

forword只有一次請求,而redirect有兩次請求。

17.Session和Cookie的區(qū)別

Cookie 是保存在客戶端的一小塊文本串的數(shù)據(jù)??蛻舳讼蚍?wù)器發(fā)起請求時,服務(wù)器會向客戶端發(fā)送一個 Cookie,客戶端就把 Cookie 保存起來。下次向同一服務(wù)器再發(fā)起請求時,Cookie 就被攜帶發(fā)送到服務(wù)器。服務(wù)器可以根據(jù)這個 Cookie 判斷用戶的身份和狀態(tài)。

Session 指的是服務(wù)器和客戶端一次會話的過程。它是另一種記錄客戶端狀態(tài)的機(jī)制。不同的是 Cookie 是保存在客戶端瀏覽器中的,而 Session 是保存在服務(wù)器上的。客戶端瀏覽器在訪問服務(wù)器時,服務(wù)器會把客戶端信息以某種形式記錄在服務(wù)器上,這就是 Session。客戶端瀏覽器再次訪問時只需要從該 Session 中查找用戶的狀態(tài)。

Session 和 Cookie 到底有什么不同呢?

圖片

Session 和 Cookie 有什么關(guān)聯(lián)呢?

可以使用 Cookie 記錄 Session 的唯一標(biāo)識

圖片

用戶第一次請求服務(wù)器時,服務(wù)器根據(jù)用戶提交的信息,創(chuàng)建對應(yīng)的Session,請求返回時將此Session的唯一標(biāo)識信息SessionID返回給瀏覽器,瀏覽器會將此SessionID信息存入Cookie中,同時Cookie記錄此SessionID是屬于哪個域名的。

當(dāng)用戶第二次訪問服務(wù)器時,請求會自動判斷此域名下是否存在Cookie信息,如果存在,則自動將Cookie信息也發(fā)送給服務(wù)器,服務(wù)器會從Cookie中獲取SessionID,再根據(jù) SessionID 查找對應(yīng)的 Session 信息,如果沒有找到則說明用戶沒有登錄或者登錄失效,如果找到則證明用戶已經(jīng)登錄可執(zhí)行后面的操作。

分布式環(huán)境下 Session 該怎么處理呢?

分布式環(huán)境下,客戶端請求經(jīng)過負(fù)載均衡,可能會分配到不同的服務(wù)器上,假如一個用戶的請求兩次沒有落到同一臺服務(wù)器上,那么在新的服務(wù)器上就沒有記錄該用戶狀態(tài)對應(yīng)的 Session。

可以使用 Redis 等分布式緩存來存儲 Session,保證在多臺服務(wù)器間共享。

圖片

客戶端如果無法使用 Cookie 怎么辦呢?

有可能客戶端無法使用 Cookie,比如瀏覽器禁用 Cookie,或者客戶端是 安卓、IOS 設(shè)備等。

這時候怎么辦呢?SessionID 怎么存呢?怎么傳給服務(wù)器呢?

首先是 SessionID 的存儲,可以使用客戶端的本地存儲,比如瀏覽器的 sessionStorage。

接下來要怎么傳呢?

  1. 拼接到 URL:直接把 SessionID 作為 URL 的請求參數(shù)。
  2. 放到請求頭:把 SessionID 放到請求頭里面,比較常用。

18.詳細(xì)說一下 TCP 的三次握手機(jī)

圖片

TCP 三次握手過程:

最開始,客戶端和服務(wù)端都處于 CLOSE(關(guān)閉)狀態(tài),服務(wù)端監(jiān)聽客戶端的請求,進(jìn)入 LISTEN(監(jiān)聽) 狀態(tài)。

客戶端發(fā)送連接請求,進(jìn)行第一次握手(同步位 SYN=1,序號字段 seq=x),發(fā)送完畢后,客戶端就進(jìn)入 SYN_SENT(同步已發(fā)送) 狀態(tài)。

服務(wù)端確認(rèn)連接,進(jìn)行第二次握手(同步位 SYN=1,確認(rèn)位 ACK=1,序號字段 seq=y,確認(rèn)號字段 ack=x+1), 發(fā)送完畢后,服務(wù)端就進(jìn)入 SYN_RCV(同步已接收) 狀態(tài)。

客戶端收到服務(wù)端的確認(rèn)后,再次向服務(wù)端確認(rèn),進(jìn)行第三次握手(確認(rèn)位 ACK=1,確認(rèn)號字段 ack=y+1),發(fā)送完畢后,客戶端就進(jìn)入 ESTABLISHED(連接已建立) 狀態(tài),當(dāng)服務(wù)端接收到這個包時,也進(jìn)入 ESTABLISHED(連接已建立) 狀態(tài)。

需要C/C++ Linux服務(wù)器架構(gòu)師學(xué)習(xí)資料加qun812855908獲?。?a href="http://ttokpm.com/soft/special/" target="_blank">資料包括C/C++,Linux,golang技術(shù),Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒體,CDN,P2P,K8S,Docker,TCP/IP,協(xié)程,DPDK,ffmpeg等),免費(fèi)分享

圖片

19.TCP 握手為什么是三次,為什么不能是兩次?不能是四次?

為什么不能是兩次?

防止已失效的連接請求報(bào)文段突然又傳到服務(wù)端,因而產(chǎn)生錯誤

圖片

客戶端發(fā)送出去的第一個連接請求報(bào)文段并沒有丟失,而是因?yàn)槟承┪粗蛟谀硞€網(wǎng)絡(luò)節(jié)點(diǎn)上發(fā)生滯留,導(dǎo)致延遲到連接釋放以后的某個時間點(diǎn)才到達(dá)服務(wù)端。

本來這是一個早已失效的報(bào)文段,但是服務(wù)端收到此失效的報(bào)文段后,會誤認(rèn)為這是客戶端再次發(fā)起的一個新的連接請求,于是服務(wù)端向客戶端又發(fā)出確認(rèn)報(bào)文,表示同意建立連接。

如果不采用 “三次握手”,那么只要服務(wù)端發(fā)出確認(rèn)報(bào)文后就會認(rèn)為新的連接已經(jīng)建立了,但是客戶端并沒有發(fā)出建立連接的請求,因此不會向服務(wù)端發(fā)送數(shù)據(jù),服務(wù)端沒有收到數(shù)據(jù)就會一直等待,這樣服務(wù)端就會白白浪費(fèi)掉很多資源。

所以我們需要 “第三次握手” 來確認(rèn)這個過程:

通過第三次握手的數(shù)據(jù)來告訴服務(wù)端,客戶端有沒有收到服務(wù)端 “第二次握手” 時傳過去的數(shù)據(jù),以及這個連接的序號是不是有效的。

若發(fā)送的這個數(shù)據(jù)是 “收到且沒有問題” 的信息,服務(wù)端接收后就可以正常建立 TCP 連接,否則建立 TCP 連接失敗,服務(wù)器關(guān)閉連接端口。由此減少服務(wù)器開銷和接收到失效請求時發(fā)生的錯誤。

為什么不是四次?

簡單來說,就是三次握手已經(jīng)足夠創(chuàng)建可靠的連接,沒有必要再多一次握手導(dǎo)致花費(fèi)更多的時間在建立連接上。

20.三次握手中每一次沒收到報(bào)文會發(fā)生什么情況?

第一次握手服務(wù)端未收到 SYN 報(bào)文

服務(wù)端不會進(jìn)行任何的動作,而客戶端由于一段時間內(nèi)沒有收到服務(wù)端發(fā)來的確認(rèn)報(bào)文,等待一段時間后會重新發(fā)送 SYN 報(bào)文,

如果仍然沒有回應(yīng),會重復(fù)這個過程,直到發(fā)送次數(shù)超過最大重傳次數(shù),就會返回連接建立失敗。

第二次握手客戶端未收到服務(wù)端響應(yīng)的 ACK 報(bào)文

因?yàn)榈诙挝帐质前瑢蛻舳说谝淮挝帐值?ACK 確認(rèn)報(bào)文,所以如果客戶端遲遲沒有收到第二次握手,那么客戶端就會覺得可能是自己的 SYN 報(bào)文(第一次握手)丟失了,于是客戶端就會觸發(fā)超時重傳機(jī)制,重傳 SYN 報(bào)文。

然后,因?yàn)榈诙挝帐质前?wù)端的 SYN 報(bào)文,所以當(dāng)客戶端收到后,需要給服務(wù)端發(fā)送 ACK 確認(rèn)報(bào)文(第三次握手),服務(wù)端才會認(rèn)為該 SYN 報(bào)文被客戶端收到了。

那么,如果第二次握手丟失了,服務(wù)端就收不到第三次握手,于是服務(wù)端這邊會觸發(fā)超時重傳機(jī)制,重傳 SYN-ACK 報(bào)文。

第三次握手服務(wù)端未收到客戶端發(fā)送過來的 ACK 報(bào)文

客戶端收到服務(wù)端的 SYN-ACK 報(bào)文后,就會給服務(wù)端發(fā)送一個 ACK 報(bào)文,也就是第三次握手,此時客戶端進(jìn)入到 ESTABLISH(連接已建立) 狀態(tài)。

因?yàn)檫@個第三次握手的 ACK 是對第二次握手的 SYN 的確認(rèn)報(bào)文,所以當(dāng)?shù)谌挝帐謥G失了,如果服務(wù)端那一方遲遲收不到這個確認(rèn)報(bào)文,就會觸發(fā)超時重傳機(jī)制,重傳 SYN-ACK 報(bào)文,直到收到第三次握手,或者達(dá)到最大重傳次數(shù)。

21.第二次握手傳回了 ACK,為什么還要傳回 SYN?

ACK 是為了告訴客戶端傳來的數(shù)據(jù)已經(jīng)接收無誤。

而傳回 SYN 是為了告訴客戶端,服務(wù)端響應(yīng)的確實(shí)是客戶端發(fā)送的報(bào)文。

22.第三次握手可以攜帶數(shù)據(jù)嗎?

第三次握手是可以攜帶數(shù)據(jù)的。

此時客戶端已經(jīng)處于連接已建立狀態(tài)。對于客戶端來說,它已經(jīng)建立連接成功了,并且確認(rèn)服務(wù)端的接收和發(fā)送能力是正常的。

第一次握手不能攜帶數(shù)據(jù)是出于安全的考慮,因?yàn)槿绻试S攜帶數(shù)據(jù),攻擊者每次在 SYN 報(bào)文中攜帶大量數(shù)據(jù),就會導(dǎo)致服務(wù)端消耗更多的時間和空間去處理這些報(bào)文,會造成CPU和內(nèi)存的消耗。

23.說說 TCP 四次揮手的過程?

圖片

  • 數(shù)據(jù)傳輸結(jié)束后,通信雙方都可以主動發(fā)起斷開連接請求,這里假定客戶端發(fā)起。
  • 客戶端發(fā)送釋放連接報(bào)文,進(jìn)行第一次揮手(FIN=1,ACK=1,seq=u,ack=v),發(fā)送完畢后,客戶端進(jìn)入 FIN_WAIT_1(終止等待1) 狀態(tài)。
  • 服務(wù)端發(fā)送確認(rèn)報(bào)文,進(jìn)行第二次揮手(ACK=1,seq =v,ack=u+1),發(fā)送完畢后,服務(wù)端進(jìn)入 CLOSE_WAIT(關(guān)閉等待) 狀態(tài),客戶端收到這個確認(rèn)包后,進(jìn)入 FIN_WAIT_2(終止等待2) 狀態(tài)。
  • 服務(wù)端發(fā)送釋放連接報(bào)文,進(jìn)行第三次揮手(FIN=1,ACK1,seq=w,ack=u+1),發(fā)送完畢后,服務(wù)端進(jìn)入LAST_ACK(最后確認(rèn)) 狀態(tài),等待來自客戶端的最后一個 ACK 報(bào)文。
  • 客戶端發(fā)送確認(rèn)報(bào)文,進(jìn)行第四次揮手(ACK=1,seq=u+1,ack=w+1),客戶端收到來自服務(wù)端的關(guān)閉請求,發(fā)送一個確認(rèn)包,并進(jìn)入 TIME_WAIT(時間等待) 狀態(tài),服務(wù)端接收到這個確認(rèn)包后,關(guān)閉連接,進(jìn)入 CLOSED(關(guān)閉) 狀態(tài)。
  • 客戶端再經(jīng)過 2MSL 后,也進(jìn)入 CLOSED(關(guān)閉) 狀態(tài)。

客戶端在發(fā)送完最后一個確認(rèn)報(bào)文后,為什么不直接進(jìn)入關(guān)閉狀態(tài) ? 而是要進(jìn)入時間等待狀態(tài),2MSL 后才進(jìn)入關(guān)閉狀態(tài),這是否有必要呢 ?

圖片

服務(wù)端發(fā)送TCP連接釋放報(bào)文段后進(jìn)入最后確認(rèn)狀態(tài)。

客戶端收到該報(bào)文段后,發(fā)送普通的TCP確認(rèn)報(bào)文段,并進(jìn)入關(guān)閉狀態(tài)而不是時間等待狀態(tài)。然而,該TCP確認(rèn)報(bào)文段丟失了。

這必然會造成服務(wù)端對之前所發(fā)送的TCP連接釋放報(bào)文段的超時重傳,并仍處于最后確認(rèn)狀態(tài)。重傳的TCP連接釋放報(bào)文段到達(dá)客戶端,由于客戶端處于關(guān)閉狀態(tài),因此不理睬該報(bào)文段,這必然會造成服務(wù)端反復(fù)重傳TCP連接釋放報(bào)文段,并一直處于最后確認(rèn)狀態(tài)而無法進(jìn)入關(guān)閉狀態(tài)。

因此時間等待狀態(tài)以及處于該狀態(tài)2MSL時長,可以確保服務(wù)端可以收到最后一個TCP確認(rèn)報(bào)文段而進(jìn)入關(guān)閉狀態(tài)。

另外,客戶端在發(fā)送完最后一個TCP確認(rèn)報(bào)文段后,再經(jīng)過2MSL時長,就可以使本次連接持續(xù)時間內(nèi)所產(chǎn)生的所有報(bào)文段都從網(wǎng)絡(luò)中消失,這樣就可以使下一個新的TCP連接中,不會出現(xiàn)舊連接中的報(bào)文段。

為什么等待時間是2MSL?

MSL 是報(bào)?最??存時間,它是任何報(bào)?在?絡(luò)上存在的最?時間,超過這個時間報(bào)?將被丟棄。

TIME_WAIT 等待 2 倍的 MSL,是因?yàn)?絡(luò)中可能存在來?發(fā)送?的數(shù)據(jù)包,當(dāng)這些發(fā)送?的數(shù)據(jù)包被接收?處理后?會向?qū)?發(fā)送響應(yīng),所以?來?回需要等待 2 倍的時間。

?如服務(wù)端如果沒有收到客戶端發(fā)送的TCP確認(rèn)報(bào)文段,就會觸發(fā)超時重傳,重新發(fā)送TCP連接釋放報(bào)文段,客戶端收到后,會重發(fā)TCP確認(rèn)報(bào)文段給服務(wù)端, ?來?去正好 2 個 MSL。

24.TCP 揮手為什么需要四次呢?

再來回顧下四次揮手雙方發(fā) FIN 包的過程,就能理解為什么需要四次了。

關(guān)閉連接時,客戶端向服務(wù)端發(fā)送 FIN 報(bào)文,僅僅表示客戶端不再發(fā)送數(shù)據(jù)了但是還能接收數(shù)據(jù)。

服務(wù)端收到客戶端的 FIN 報(bào)文后,先返回一個 ACK 確認(rèn)報(bào)文;而服務(wù)端可能還有數(shù)據(jù)需要處理和發(fā)送,等服務(wù)端不再發(fā)送數(shù)據(jù)了,再發(fā)送 FIN 報(bào)文給客戶端來表示同意現(xiàn)在關(guān)閉連接。

從上面的過程可知,服務(wù)端通常需要等待完成數(shù)據(jù)的發(fā)送和處理,所以服務(wù)端的 ACK 和 FIN 一般都會分開發(fā)送,從而導(dǎo)致比三次握手多了一次。

25.TCP ?;钣?jì)時器有什么用?

除了時間等待計(jì)時器外,TCP 還有一個?;钣?jì)時器(keepalive timer)。

設(shè)想這樣的場景:

TCP 雙方已經(jīng)建立了連接,后來,客戶端的主機(jī)突然出現(xiàn)了故障。顯然,服務(wù)端以后就不能再收到客戶端發(fā)來的數(shù)據(jù)。因此,應(yīng)當(dāng)有措施使服務(wù)端不要再白白等待下去。這就需要使用保活計(jì)時器了。

服務(wù)端每收到一次客戶端的數(shù)據(jù),就重新設(shè)置并啟動?;钣?jì)時器(2小時定時)。若定時周期內(nèi)都沒有收到客戶端發(fā)來的數(shù)據(jù),服務(wù)端就發(fā)送一個探測報(bào)文段,以后每隔 75 秒鐘發(fā)送一次。若連續(xù)發(fā)送 10 個探測報(bào)文段后仍然無客戶端的響應(yīng),服務(wù)端就認(rèn)為客戶端出了故障,接著就關(guān)閉這個連接。

26.CLOSE-WAIT 的狀態(tài)和意義?

服務(wù)端收到客戶端關(guān)閉連接的請求并確認(rèn)之后,就會進(jìn)入 CLOSE-WAIT 狀態(tài)。

此時服務(wù)端可能還有一些數(shù)據(jù)沒有傳輸完成,因此不能立即關(guān)閉連接,而 CLOSE-WAIT 狀態(tài)就是為了保證服務(wù)端在關(guān)閉連接之前將待發(fā)送的數(shù)據(jù)處理完。

27.說說 TCP 報(bào)文首部有哪些字段?

圖片

16位端口號:源端口號,標(biāo)識發(fā)送該 TCP 報(bào)文段的應(yīng)用進(jìn)程;目的端口號,標(biāo)識接收該 TCP 報(bào)文段的應(yīng)用進(jìn)程。

32位序號:指出本 TCP 報(bào)文段數(shù)據(jù)載荷的第一個字節(jié)的序號。32位序號:指出本 TCP 報(bào)文段數(shù)據(jù)載荷的第一個字節(jié)的序號。

32位確認(rèn)號:指出期望收到對方下一個 TCP 報(bào)文段的數(shù)據(jù)載荷的第一個字節(jié)的序號,同時也是對之前收到的所有數(shù)據(jù)的確認(rèn)。若確認(rèn)號 = n,則表明到序號 n-1 為止的所有數(shù)據(jù)都已正確接收,期望收到序號為 n 的數(shù)據(jù)。

4位頭部長度:指出 TCP 報(bào)文段的首部長度。

6位標(biāo)志位:

  • 確認(rèn)標(biāo)志位ACK:取值為1時確認(rèn)號字段才有效,取值為0時確認(rèn)號字段無效。TCP 規(guī)定,在連接建立后所有傳送的 TCP 報(bào)文段都必須把 ACK 置為1。
  • 同步標(biāo)志位SYN:在 TCP 連接建立時用來同步序號。
  • 終止標(biāo)志位FIN:用來釋放 TCP 連接。

16位窗口大?。?/p>

  • 指出發(fā)送本報(bào)文段的一方的接收窗口。
  • 窗口值作為接收方讓發(fā)送方設(shè)置其發(fā)送窗口的依據(jù)。
  • 這是以接收方的接收能力來控制發(fā)送方的發(fā)送能力,稱為流量控制。
  • 發(fā)送窗口的大小還取決于擁塞窗口的大小,也就是應(yīng)該從接收窗口和擁塞窗口中取小者。

16位校驗(yàn)和:用來檢查整個 TCP 報(bào)文段在傳輸過程中是否出現(xiàn)了誤碼。

16位緊急指針:當(dāng)發(fā)送方有緊急數(shù)據(jù)時,可將緊急數(shù)據(jù)插隊(duì)到發(fā)送緩存的最前面,并立刻封裝到一個 TCP 報(bào)文段中進(jìn)行發(fā)送。緊急指針會指出本報(bào)文段的數(shù)據(jù)載荷部分包含了多長的緊急數(shù)據(jù),緊急數(shù)據(jù)之后是普通數(shù)據(jù)。

28.TCP 是如何保證可靠性的?

TCP主要提供了 連接管理、校驗(yàn)和、序列號/確認(rèn)應(yīng)答、流量控制、最大消息長度、超時重傳、擁塞控制等方式實(shí)現(xiàn)了可靠傳輸。

連接管理:TCP 使用三次握手和四次揮手來保證可靠地建立連接和釋放連接。

校驗(yàn)和:用來檢查整個 TCP 報(bào)文段在傳輸過程中是否出現(xiàn)了誤碼。

序列號/確認(rèn)應(yīng)答:TCP 會給發(fā)送的每一個包進(jìn)行編號,接收方會對收到的包進(jìn)行應(yīng)答,發(fā)送方就會知道接收方是否收到對應(yīng)的包,如果發(fā)現(xiàn)沒有收到,就會重發(fā),這樣就能保證數(shù)據(jù)的完整性了。

流量控制:TCP 連接的每一方都有固定大小的緩沖空間,TCP 的接收端只允許發(fā)送端發(fā)送接收端緩沖區(qū)能接納的數(shù)據(jù)大小。當(dāng)接收方來不及處理發(fā)送方的數(shù)據(jù)時,能提示發(fā)送方降低發(fā)送的速率,防止包丟失。TCP 使用的流量控制協(xié)議是可變大小的滑動窗口協(xié)議。(TCP 利用滑動窗口實(shí)現(xiàn)流量控制)

最大消息長度:在建立 TCP 連接的時候,雙方約定一個最大的長度(MSS)作為發(fā)送的單位,重傳的時候也是以這個單位來進(jìn)行重傳的。理想情況下是該長度的數(shù)據(jù)剛好不被網(wǎng)絡(luò)層分塊。

超時重傳:超時重傳是指發(fā)送出去的數(shù)據(jù)包到接收到確認(rèn)包之間的時間,如果超過了這個時間,就會被認(rèn)為是丟包了,需要重傳。

擁塞控制:如果網(wǎng)絡(luò)非常擁堵,此時再發(fā)送數(shù)據(jù)就會加重網(wǎng)絡(luò)負(fù)擔(dān),那么發(fā)送的數(shù)據(jù)段很可能超過了最大生存時間也沒有到達(dá)接收方,就會產(chǎn)生丟包問題。為此 TCP 引入了慢啟動機(jī)制,先發(fā)出少量數(shù)據(jù),就像探路一樣,先摸清當(dāng)前的網(wǎng)絡(luò)擁堵狀態(tài)后,再決定按照多大的速度傳送數(shù)據(jù)。

29.說說 TCP 的流量控制?

TCP 提供了一種機(jī)制,可以讓發(fā)送方根據(jù)接收方的實(shí)際接收能力控制發(fā)送的數(shù)據(jù)量,這就是流量控制。

TCP 通過「滑動窗口」來實(shí)現(xiàn)流量控制

首先 TCP 雙方進(jìn)行三次握手,初始化各自的窗口大小,均為 400 字節(jié)。

圖片

假如當(dāng)前發(fā)送方給接收方發(fā)送了 200 字節(jié),那么,發(fā)送方的SND.NXT會右移 200 字節(jié),也就是說當(dāng)前的可用窗口減少了 200 字節(jié)。

接收方收到后,放到緩沖隊(duì)列里面,REV.WND = 400-200=200 字節(jié),所以 win=200 字節(jié)返回給發(fā)送方。接收方會在 ACK 的報(bào)文首部帶上縮小后的滑動窗口 200 字節(jié)

發(fā)送方又發(fā)送 200 字節(jié)過來,200 字節(jié)到達(dá),繼續(xù)放到緩沖隊(duì)列里面。不過這時候,由于大量負(fù)載的原因,接收方處理不了這么多字節(jié),只能處理 100 字節(jié),剩余的 100 字節(jié)繼續(xù)放到緩沖隊(duì)列里面。這時候,REV.WND = 400-200-100=100 字節(jié),即 win=100 字節(jié)返回給發(fā)送方。

發(fā)送方繼續(xù)發(fā)送 100 字節(jié)過來,這時候,接收窗口 win 變?yōu)?0。

發(fā)送方停止發(fā)送,開啟一個定時任務(wù),每隔一段時間,就去詢問接收方,直到 win 大于 0,才開始繼續(xù)發(fā)送。

30.詳細(xì)說說 TCP 的滑動窗口?

TCP 發(fā)送一個數(shù)據(jù),如果需要收到確認(rèn)應(yīng)答才會發(fā)送下一個數(shù)據(jù)。這樣的話就會有個缺點(diǎn):效率會比較低。

為了解決這個問題,TCP 引入了滑動窗口,它是操作系統(tǒng)開辟的一個緩存空間。窗口大小表示無需等待確認(rèn)應(yīng)答而可以繼續(xù)發(fā)送數(shù)據(jù)的最大值。

TCP 頭部有個 16 位的窗口大小,它告訴對方本端的 TCP 接收緩沖區(qū)還能容納多少字節(jié)的數(shù)據(jù),這樣對方就可以控制發(fā)送數(shù)據(jù)的速度,從而達(dá)到流量控制的目的。

通俗點(diǎn)講,就是接收方每次收到數(shù)據(jù)包,在發(fā)送確認(rèn)報(bào)文的時候,同時告訴發(fā)送方,自己的接收緩沖區(qū)還有多少空閑空間,緩沖區(qū)的空閑空間,我們就稱之為接收窗口大小。

TCP 滑動窗口分為兩種: 發(fā)送窗口和接收窗口。

發(fā)送方的滑動窗口包含四個部分:

  1. 已發(fā)送且已收到 ACK 確認(rèn)
  2. 已發(fā)送但未收到 ACK 確認(rèn)
  3. 未發(fā)送但可以發(fā)送
  4. 未發(fā)送且不可發(fā)送

圖片

  • 虛線矩形框,就是發(fā)送窗口。
  • SND.WND:表示發(fā)送窗口的大小,上圖虛線框的格子數(shù)是 14 個,即發(fā)送窗口大小是 14。
  • SND.NXT:下一個發(fā)送的位置,它指向未發(fā)送但可以發(fā)送的第一個字節(jié)的序列號。
  • SND.UNA:一個絕對指針,它指向的是已發(fā)送但未收到確認(rèn)的第一個字節(jié)的序列號。

接收方的滑動窗口包含三個部分:

  1. 已成功接收并確認(rèn)
  2. 未收到數(shù)據(jù)但可以接收
  3. 未收到數(shù)據(jù)且不可以接收的數(shù)據(jù)

圖片

  • 虛線矩形框,就是接收窗口。
  • REV.WND:表示接收窗口的大小,上圖虛線框的格子數(shù)就是 9 個,即接收窗口的大小是 9。
  • REV.NXT:下一個接收的位置,它指向未收到但可以接收的第一個字節(jié)的序列號。

31.說說 TCP 的擁塞控制?

什么是擁塞控制?不是有了流量控制嗎?

前?的流量控制是避免發(fā)送?的數(shù)據(jù)填滿接收?的緩存,但是并不知道整個?絡(luò)中發(fā)?了什么。

?般來說,計(jì)算機(jī)?絡(luò)都處在?個共享的環(huán)境。因此也有可能會因?yàn)槠渌鳈C(jī)之間的通信使得?絡(luò)出現(xiàn)擁堵。

在?絡(luò)出現(xiàn)擁堵時,如果繼續(xù)發(fā)送?量數(shù)據(jù)包,可能會導(dǎo)致數(shù)據(jù)包延遲、丟失等,這時 TCP 就會重傳數(shù)據(jù),但是?重傳就會導(dǎo)致?絡(luò)的負(fù)擔(dān)更重,于是會導(dǎo)致更?的延遲以及更多的丟包,這個情況就會進(jìn)?惡性循環(huán)并且被不斷地放?…

所以,TCP 不能忽略整個網(wǎng)絡(luò)中發(fā)?的事,它被設(shè)計(jì)成?個?私的協(xié)議,當(dāng)?絡(luò)發(fā)送擁塞時,TCP 會?我犧牲,降低發(fā)送的數(shù)據(jù)流。

于是,就有了擁塞控制,擁塞控制的?的就是為了避免發(fā)送?的數(shù)據(jù)填滿整個?絡(luò)。

就像是一個水管,不能讓太多的水(數(shù)據(jù)流)流入水管,如果超過水管的承受能力,水管就會被撐爆(丟包)。

發(fā)送方維護(hù)一個擁塞窗口 cwnd(congestion window) 的變量,調(diào)節(jié)所要發(fā)送數(shù)據(jù)的量。

什么是擁塞窗??和發(fā)送窗?有什么關(guān)系呢?

擁塞窗? **cwnd **是發(fā)送?維護(hù)的?個狀態(tài)變量,它會根據(jù)?絡(luò)的擁塞程度動態(tài)變化。

發(fā)送窗? swnd 和接收窗? rwnd 是約等于的關(guān)系,那么由于加?了擁塞窗?的概念后,此時發(fā)送窗?的值 swnd = min(cwnd, rwnd),也就是取擁塞窗?和接收窗?中的最?值。

擁塞窗? cwnd 變化的規(guī)則:

  • 只要?絡(luò)中沒有出現(xiàn)擁塞, cwnd 就會增?
  • 但如果?絡(luò)中出現(xiàn)了擁塞, cwnd 就會減小

擁塞控制有哪些常用算法?

慢啟動

慢啟動算法,慢慢啟動。

它表示 TCP 建立連接完成后,一開始不要發(fā)送大量的數(shù)據(jù),而是先探測一下網(wǎng)絡(luò)的擁塞程度。由小到大逐漸增加擁塞窗口的大小,如果沒有出現(xiàn)丟包,每收到一個 ACK,就將擁塞窗口 cwnd 的大小加 1(單位是 MSS)。每輪次發(fā)送窗口增加一倍,呈指數(shù)增長,如果出現(xiàn)丟包,擁塞窗口就減半,進(jìn)入擁塞避免階段。

舉個例子:

  • 連接建?完成后,?開始初始化 cwnd = 1 ,表示可以傳?個 MSS ??的數(shù)據(jù)。
  • 當(dāng)收到?個 ACK 確認(rèn)應(yīng)答后,cwnd 增加 1,于是?次性能夠發(fā)送 2 個。
  • 當(dāng)收到 2 個 ACK 確認(rèn)應(yīng)答后, cwnd 增加 2,于是就能?之前多發(fā)送 2 個,所以這?次能夠發(fā)送 4 個。
  • 當(dāng)這 4 個 ACK 確認(rèn)到來的時候,每個確認(rèn) cwnd 增加 1, 4 個確認(rèn) cwnd 增加 4,于是就能?之前多發(fā)送 4 個,所以這?次能夠發(fā)送 8 個。

圖片

發(fā)送包的個數(shù)是呈指數(shù)性增?的。

圖片

為了防止 cwnd 增長過大而引起網(wǎng)絡(luò)擁塞,還需設(shè)置一個慢啟動閥值 ssthresh(slow start threshold)的狀態(tài)變量。當(dāng) cwnd 到達(dá)該閥值后,就好像水管被關(guān)小了水龍頭一樣,減少了擁塞狀態(tài)。即當(dāng) cwnd > ssthresh 時,進(jìn)入擁塞避免算法。

擁塞避免

一般來說,慢啟動閥值 ssthresh 的大小是 65535 字節(jié),cwnd 到達(dá)慢啟動閥值后

  • 每收到一個 ACK 時,cwnd = cwnd + 1/cwnd
  • 當(dāng)每過一個 RTT 時,cwnd = cwnd + 1

顯然這是一個線性上升的算法,可以避免發(fā)送過快導(dǎo)致網(wǎng)絡(luò)出現(xiàn)擁塞問題。

接著上面慢啟動的例子,假定 ssthresh 為 8:

  • 當(dāng) 8 個 ACK 確認(rèn)應(yīng)答到來時,每個確認(rèn)增加 1/8,8 個 ACK 確認(rèn)后 cwnd ?共增加 1,于是這?次能夠發(fā)送 9 個 MSS ??的數(shù)據(jù),變成了線性增?。

圖片

擁塞發(fā)生

當(dāng)網(wǎng)絡(luò)擁塞發(fā)生丟包時,會有兩種情況:

  • RTO 超時重傳
  • 快速重傳

如果是發(fā)生了RTO 超時重傳,就會使用「擁塞發(fā)生」算法

  • 慢啟動閥值 sshthresh = cwnd/2
  • cwnd 重置為 1
  • 進(jìn)入新的慢啟動過程

圖片

這真的是辛辛苦苦幾十年,一朝回到解放前。其實(shí)還有更好的處理方式,就是「快速重傳」。當(dāng)發(fā)送方收到 3 個連續(xù)的重復(fù) ACK 時,就會快速地重傳,不必等待RTO超時再重傳。

圖片

發(fā)?「快速重傳」的擁塞發(fā)?算法:

  • 擁塞窗口大小 cwnd = cwnd/2
  • 慢啟動閥值 ssthresh = cwnd
  • 進(jìn)入快速恢復(fù)算法

快速恢復(fù)

快速重傳和快速恢復(fù)算法一般是同時使用的。快速恢復(fù)算法認(rèn)為,還能收到 3 個重復(fù)的 ACK,說明網(wǎng)絡(luò)也沒有那么糟糕,所以沒必要像 RTO超時重傳 那樣強(qiáng)烈。

正如前面所說的,進(jìn)入快速恢復(fù)之前,cwnd 和 sshthresh 已被更新:

  • cwnd = cwnd/2
  • sshthresh = cwnd

然后,真正進(jìn)入「快速恢復(fù)」算法:

  • cwnd = sshthresh + 3
  • 重傳重復(fù)的那幾個 ACK(即丟失的那幾個數(shù)據(jù)包)
  • 如果再收到重復(fù)的 ACK,那么 cwnd = cwnd +1
  • 如果收到新數(shù)據(jù)的 ACK 后,cwnd = sshthresh。因?yàn)槭盏叫聰?shù)據(jù)的 ACK,表明恢復(fù)過程已經(jīng)結(jié)束,可以再次進(jìn)入「擁塞避免」算法了。

圖片

32.說說 TCP 的重傳機(jī)制?

重傳包括:超時重傳、快速重傳、帶選擇確認(rèn)的重傳(SACK)、重復(fù) SACK 四種。

超時重傳

超時重傳,是 TCP 協(xié)議保證數(shù)據(jù)可靠性的另一個重要機(jī)制,其原理是在發(fā)送某一個數(shù)據(jù)以后就開啟一個重傳計(jì)時器,在一定時間內(nèi)如果沒有收到發(fā)送的數(shù)據(jù)報(bào)的 ACK 報(bào)文,那么就重新發(fā)送數(shù)據(jù),直到收到 ACK 報(bào)文為止。

超時時間應(yīng)該設(shè)置為多少合適呢?

圖片

RTT 就是數(shù)據(jù)完全發(fā)送完,到收到確認(rèn)信號的時間,即數(shù)據(jù)包的一次往返時間。

超時重傳時間,就是 RTO(Retransmission Timeout)。那么,RTO 應(yīng)該設(shè)置多大呢?

  • 如果 RTO 設(shè)置很大,等了很久都沒重發(fā),這樣肯定不行。
  • 如果 RTO 設(shè)置很小,那很可能數(shù)據(jù)都沒有丟失,就開始重發(fā)了,這將會導(dǎo)致網(wǎng)絡(luò)阻塞,從而發(fā)生惡性循環(huán),導(dǎo)致更多的超時出現(xiàn)。

一般來說,RTO 略微大于 RTT,效果是最佳的。

超時重傳并不是十分完美的重傳方案,它有這些缺點(diǎn):

  • 當(dāng)一個報(bào)文丟失時,會等待一定的超時周期,才重傳分組,增加了端到端的時延。
  • 當(dāng)一個報(bào)文丟失時,在其等待超時的過程中,可能會出現(xiàn)這種情況:其后面的報(bào)文段已經(jīng)被接收方接收了但卻遲遲得不到確認(rèn),發(fā)送方會認(rèn)為其后面的報(bào)文段也丟失了,從而引起不必要的重傳,既浪費(fèi)資源也浪費(fèi)時間。

快速重傳

快速重傳可以用來解決超時重發(fā)的時間等待問題。

它不以時間驅(qū)動,而是以數(shù)據(jù)驅(qū)動。它是基于接收方的反饋信息來引發(fā)重傳的。

快速重傳的流程如下:

圖片

發(fā)送方發(fā)送了 1,2,3,4,5,6 份數(shù)據(jù):

  • 第一份 Seq=1 先送到了,于是 ACK 回2;
  • 第二份 Seq=2 也送到了,于是 ACK 回3;
  • 第三份 Seq=3 由于網(wǎng)絡(luò)等某些原因,沒送到;
  • 第四份 Seq=4 送到了,但是由于 Seq=3 沒收到。因此 ACK 還是回3;
  • 后面的 Seq=5,6 也送到了,ACK 還是回復(fù)3,因?yàn)?Seq=3 沒有收到。
  • 發(fā)送方連續(xù)收到三個重復(fù)冗余的 ACK=3 的確認(rèn)(其實(shí)是4個哈,但是因?yàn)榍懊娴囊粋€是正常的ACK,后面三個才是重復(fù)冗余的),于是知道哪個報(bào)文段在傳輸過程中丟失了;發(fā)送方就在重傳定時器過期之前,重傳該報(bào)文段。
  • 最后,接收方收到了 Seq=3,此時因?yàn)?Seq=4,5,6 都收到了,于是它回 ACK=7。

快速重傳機(jī)制也有缺點(diǎn):發(fā)送方并不知道到底是哪個報(bào)文丟失了,到底該重傳多少個數(shù)據(jù)包?

是只重傳 Seq=3 ?還是重傳 Seq=3、Seq=4、Seq=5、Seq=6 呢?因?yàn)榘l(fā)送方并不清楚這三個連續(xù)的 ACK=3 是誰傳回來的。

帶選擇確認(rèn)的重傳(SACK)

為了解決應(yīng)該重傳多少個包的問題? TCP 提供了帶選擇確認(rèn)的重傳(即 SACK,Selective Acknowledgment)。

SACK 機(jī)制就是,在快速重傳的基礎(chǔ)上,接收方返回最近收到報(bào)文段的序列號范圍,這樣發(fā)送方就知道接收方哪些數(shù)據(jù)包是沒收到的。這樣就很清楚應(yīng)該重傳哪些數(shù)據(jù)包。

圖片

如上圖中,發(fā)送?收到了三次同樣的 ACK 確認(rèn)報(bào)?,于是就會觸發(fā)「快速重傳」機(jī)制,通過 SACK 信息發(fā)現(xiàn)只有 200~299 這段數(shù)據(jù)丟失,則重發(fā)時,就只選擇了這個 TCP 段進(jìn)?重發(fā)。

重復(fù) SACK(D-SACK)

D-SACK,英文是 Duplicate SACK,是在 SACK 的基礎(chǔ)上做了一些擴(kuò)展,主要用來告訴發(fā)送方,有哪些數(shù)據(jù)包,自己重復(fù)接受了。

D-SACK 的目的是幫助發(fā)送方判斷,是否發(fā)生了包失序、ACK 丟失、包重復(fù)或偽重傳。讓 TCP 可以更好的做網(wǎng)絡(luò)流控。

例如 ACK 丟包導(dǎo)致的數(shù)據(jù)包重復(fù):

圖片

  • 接收?發(fā)給發(fā)送?的兩個 ACK 確認(rèn)應(yīng)答都丟失了,所以發(fā)送?超時后,重傳第?個數(shù)據(jù)包(3000 ~ 3499)
  • 接收?發(fā)現(xiàn)數(shù)據(jù)是重復(fù)收到的,于是回了?個 SACK = 30003500,告訴「發(fā)送?」 30003500的數(shù)據(jù)早已被接收了,因?yàn)?ACK 都到 4000 了,意味著 4000 之前的所有數(shù)據(jù)都已經(jīng)收到了,所以這個 SACK 就代表著 D-SACK 。這樣發(fā)送?就知道了,數(shù)據(jù)并沒有丟,而是接收?的 ACK 確認(rèn)報(bào)?丟了。

33.說說 TCP 的粘包和拆包?

什么是 TCP 粘包和拆包?

TCP 是面向字節(jié)流,沒有界限的一串?dāng)?shù)據(jù)。TCP 底層并不了解上層業(yè)務(wù)數(shù)據(jù)的具體含義,它會根據(jù) TCP 緩沖區(qū)的實(shí)際情況進(jìn)行包的劃分,所以在業(yè)務(wù)上認(rèn)為,一個完整的包可能會被 TCP 拆分成多個包進(jìn)行發(fā)送,也有可能把多個小的包封裝成一個大的數(shù)據(jù)包進(jìn)行發(fā)送,這就是所謂的 TCP 粘包和拆包問題。

圖片

為什么會產(chǎn)生粘包和拆包呢?

  • 要發(fā)送的數(shù)據(jù)小于 TCP 發(fā)送緩沖區(qū)的大小,TCP 將多次寫入緩沖區(qū)的數(shù)據(jù)一次性發(fā)送出去,將會發(fā)生粘包;
  • 接收方的應(yīng)用層沒有及時讀取接收緩沖區(qū)的數(shù)據(jù),將會發(fā)生粘包;
  • 要發(fā)送的數(shù)據(jù)大于 TCP 發(fā)送緩沖區(qū)剩余空間的大小,將會發(fā)生拆包;
  • 待發(fā)送的數(shù)據(jù)大于 MSS(最大報(bào)文長度),TCP 在傳輸前將會進(jìn)行拆包。即 TCP報(bào)文長度 - TCP頭部長度 > MSS。

解決方案:

  • 發(fā)送方給每個數(shù)據(jù)包添加包首部,首部中應(yīng)該至少包含數(shù)據(jù)包的長度,這樣接收方在收到數(shù)據(jù)后,通過讀取包首部的長度字段,便知道每一個數(shù)據(jù)包的實(shí)際長度了。
  • 發(fā)送方將每個數(shù)據(jù)包封裝為固定長度(不夠的可以通過補(bǔ)0填充),這樣接收方每次從接收緩沖區(qū)中讀取固定長度的數(shù)據(jù),就自然而然的把每個數(shù)據(jù)包拆分開來。
  • 可以在數(shù)據(jù)包之間設(shè)置邊界,如添加特殊符號,這樣接收方通過這個邊界就可以將不同的數(shù)據(jù)包拆分開來。
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • 主機(jī)
    +關(guān)注

    關(guān)注

    0

    文章

    982

    瀏覽量

    35008
  • TCP
    TCP
    +關(guān)注

    關(guān)注

    8

    文章

    1347

    瀏覽量

    78933
  • UDP
    UDP
    +關(guān)注

    關(guān)注

    0

    文章

    322

    瀏覽量

    33849
  • 數(shù)據(jù)鏈路
    +關(guān)注

    關(guān)注

    0

    文章

    25

    瀏覽量

    8926
收藏 人收藏

    評論

    相關(guān)推薦

    [7.2.1]--7.2TCPUDP區(qū)別

    計(jì)算機(jī)網(wǎng)絡(luò)
    jf_75936199
    發(fā)布于 :2023年02月01日 20:50:55

    第16章 UDP用戶數(shù)據(jù)報(bào)協(xié)議基礎(chǔ)知識

    ) 16.1 初學(xué)者重要提示 16.2 UDP基礎(chǔ)知識參考資料 16.3 UDP基礎(chǔ)知識點(diǎn) 16.4 TCPUDP區(qū)別 16.5總結(jié)
    發(fā)表于 11-02 17:27

    你覺得VxWorks與Linux區(qū)別是什么

    改名字。三、你覺得VxWorks與Linux區(qū)別是什么四、TCP/UDP區(qū)別基于連接與無連接;對系統(tǒng)資源的要求(TCP較多,
    發(fā)表于 12-20 07:52

    TCPUDP區(qū)別在哪

    文章目錄設(shè)計(jì)需求UDPTCP和UDP區(qū)別UI界面設(shè)計(jì)界面設(shè)計(jì)UDP代碼設(shè)計(jì)與實(shí)現(xiàn)打開UDP關(guān)閉UDP發(fā)送數(shù)據(jù)關(guān)閉
    發(fā)表于 01-18 10:23

    TCPUDP區(qū)別分析

      傳輸層協(xié)議主要有TCPUDPUDP提供無連接的通信,不能保證數(shù)據(jù)包被發(fā)送到目標(biāo)地址,典型的即時傳輸少量數(shù)據(jù)的應(yīng)用程序通常使用UDP。TCP
    發(fā)表于 09-18 10:29 ?2次下載

    TCPUDP區(qū)別 三次連接和四次斷開

    Telnet 遠(yuǎn)程登錄協(xié)議 提供遠(yuǎn)程訪問其他主機(jī)功能,允許用戶登錄,SNMP 簡單網(wǎng)絡(luò)管理協(xié)議 提供監(jiān)控網(wǎng)絡(luò)設(shè)備的方法,配置管理、統(tǒng)計(jì)信息收集,性能管理以及安全管理.
    發(fā)表于 04-28 11:08 ?2815次閱讀
    <b class='flag-5'>TCP</b>與<b class='flag-5'>UDP</b><b class='flag-5'>區(qū)別</b> 三次連接和四次斷開

    TCPUDP區(qū)別

    TCP(TransmissionControlProtocol,傳輸控制協(xié)議)是面向連接的協(xié)議,也就是說,在收發(fā)數(shù)據(jù)前,必須和對方建立可靠的連接。
    發(fā)表于 11-08 15:09 ?6273次閱讀
    <b class='flag-5'>TCP</b>與<b class='flag-5'>UDP</b>的<b class='flag-5'>區(qū)別</b>

    TCPUDP的原理以及區(qū)別

    最近重新認(rèn)知了一下TCPUDP的原理以及區(qū)別,做一個簡單的總結(jié)。
    發(fā)表于 08-08 14:34 ?1471次閱讀

    TCPUDP協(xié)議的區(qū)別

    最近重新認(rèn)知了一下TCPUDP的原理以及區(qū)別,做一個簡單的總結(jié)。
    發(fā)表于 11-03 10:25 ?857次閱讀

    淺談一下TCPUDP區(qū)別與應(yīng)用

    在單片機(jī)應(yīng)用程序開發(fā)中可能用得比較多有RS485,CAN通信等等相對簡潔一點(diǎn)的總線,由于所選用的單片機(jī)性能和資源有限,以太網(wǎng)并沒有在單片機(jī)應(yīng)用中作為一種普遍存在的對外通信接口。
    的頭像 發(fā)表于 02-06 14:55 ?749次閱讀

    udp是什么協(xié)議 TCPUDP區(qū)別

    TCP協(xié)議提供可靠的數(shù)據(jù)傳輸,UDP協(xié)議提供盡量高效的數(shù)據(jù)傳輸。TCP協(xié)議通過使用序列號、確認(rèn)應(yīng)答等機(jī)制,保證數(shù)據(jù)傳輸?shù)目煽啃?,?b class='flag-5'>UDP協(xié)議不提供可靠性保證,它只是簡單地把應(yīng)用程序傳給
    的頭像 發(fā)表于 06-26 17:47 ?1.1w次閱讀

    tcp/ip協(xié)議包含哪幾層 tcpudp區(qū)別

    TCP/IP協(xié)議包含四層,分別是網(wǎng)絡(luò)接口層(也稱物理層)、網(wǎng)絡(luò)層、傳輸層和應(yīng)用層。 網(wǎng)絡(luò)接口層: 網(wǎng)絡(luò)接口層負(fù)責(zé)將數(shù)據(jù)從應(yīng)用層傳輸?shù)轿锢砻襟w(如以太網(wǎng)、Wi-Fi等)。它使用二進(jìn)制數(shù)據(jù)流并負(fù)責(zé)數(shù)據(jù)
    的頭像 發(fā)表于 01-22 10:12 ?1333次閱讀

    udp是什么意思 簡述TCPUDP區(qū)別和聯(lián)系

    中的兩個基本協(xié)議。然而,TCPUDP之間存在一些重要的區(qū)別和聯(lián)系。 首先,TCP是一種面向連接的協(xié)議,而UDP是無連接的。這意味著通過
    的頭像 發(fā)表于 02-02 16:33 ?1183次閱讀

    能不能說一說TCPUDP區(qū)別?

    能不能說一說TCPUDP區(qū)別TCP(傳輸控制協(xié)議)和UDP(用戶數(shù)據(jù)報(bào)協(xié)議)是互聯(lián)網(wǎng)傳輸層協(xié)議的兩種常見形式。它們在數(shù)據(jù)傳輸、連接管
    的頭像 發(fā)表于 02-04 11:03 ?469次閱讀

    tcpudp區(qū)別和聯(lián)系

    一、引言 在現(xiàn)代網(wǎng)絡(luò)通信中,數(shù)據(jù)傳輸是至關(guān)重要的。為了確保數(shù)據(jù)的可靠傳輸,網(wǎng)絡(luò)協(xié)議發(fā)揮著關(guān)鍵作用。傳輸控制協(xié)議(TCP)和用戶數(shù)據(jù)報(bào)協(xié)議(UDP)是兩種常用的網(wǎng)絡(luò)協(xié)議,它們在許多應(yīng)用場景中發(fā)
    的頭像 發(fā)表于 08-16 11:06 ?488次閱讀