1.TCP和UDP的區別
TCP是面向連接的,UDP是面向無連接的;
TCP只能一對一通信,UDP支持一對一,一對多,多對一和多對多交互通信;
TCP是面向字節流的,UDP是面向報文的;
TCP是可靠傳輸,使用流量控制和擁塞控制;UDP是不可靠傳輸
TCP首部最小20字節,最大60字節;UDP首部僅8字節。
2.ISO七層模型及相關協議
物理層:建立、維護、斷開物理連接。
數據鏈路層:在物理層提供比特流服務的基礎上,建立相鄰結點之間的數據鏈路。
網絡層:進行邏輯地址尋址,實現不同網絡之間的路徑選擇,協議有ICMP、IGMP、IP等。
傳輸層:定義傳輸數據的協議端口號,以及流量控制和差錯校驗,協議有TCP、UDP。
會話層:建立、管理、終止會話,指本地主機與遠程主機正在進行的會話。
表示層:確保一個系統的應用層所發送的信息可以被另一個系統的應用層讀取。
應用層:網絡服務與最終用戶的一個接口,常見的協議有:HTTP、FTP、SMTP、DNS。
TCP/IP 四層模型
- 網絡接口層
- 網際層
- 傳輸層
- 應用層
五層體系結構
- 物理層
- 數據鏈路層
- 網絡層:IP網際協議、ARP地址轉換協議、RIP路由信息協議
- 傳輸層:TCP傳輸控制協議、UDP用戶數據報文協議
- 應用層:HTTP超文本傳輸協議、FTP文本傳輸協議、DNS域名系統
3.如何理解HTTP協議是無狀態的
當瀏覽器第一次發送請求給服務器時,服務器響應了;
如果同個瀏覽器發起第二次請求給服務器時,它還是會響應。但是呢,服務器不知道你就是剛才的那個瀏覽器。
簡而言之,服務器不會去記住你是誰,所以是無狀態協議。
4.簡述從瀏覽器地址欄輸入url到顯示主頁的過程
- DNS解析,查找域名對應的IP地址。
- 與服務器通過三次握手,建立TCP連接。
- 向服務器發送HTTP請求。
- 服務器處理請求,返回網頁內容。
- 瀏覽器解析并渲染頁面。
- TCP四次握手,連接結束。
5.說下 HTTP/1.0,1.1,2.0 的區別
HTTP/1.0
默認使用短連接,每次請求都需要建立一個TCP連接。它可以設置Connection: keep-alive 這個字段,強制開啟長連接。
HTTP/1.1
- 默認使用長連接,即TCP連接默認不關閉,可以被多個請求復用。
- 分塊傳輸編碼,即服務端每產生一塊數據,就發送一塊,用“流模式”取代“緩存模式”。
- 管道機制,即在同一個TCP連接里面,客戶端可以同時發送多個請求。
HTTP/2.0
- 二進制協議,1.1版本的頭信息是文本(ASCII編碼),數據體可以是文本或二進制;2.0中,頭信息和數據體都是二進制。
- 完全多路復用,在一個連接里,客戶端和服務器都可以同時發送多個請求或響應,而且不用按照順序一一對應。
- 報頭壓縮,HTTP協議不帶有狀態,每次請求都必須帶上所有信息。HTTP/2.0引入了頭信息壓縮機制,使用gzip或compress壓縮后再發送。
- 服務端推送,允許服務器未經請求,主動向客戶端發送資源。
6.POST和GET有哪些區別
7.HTTP 如何實現長連接?在什么時候會超時?
什么是HTTP的長連接?
- HTTP分為長連接和短連接,本質上說的是TCP的長短連接。TCP連接是一個雙向的通道,它是可以保持一段時間不關閉的,因此TCP連接才具有真正的長連接和短連接這一說法。
- TCP長連接可以復用一個TCP連接,來發起多次HTTP請求,這樣就可以減少資源消耗,比如一次HTML請求,如果是短連接的話,可能還需要請求后續的JS/CSS。
如何設置長連接?
通過在請求頭和響應頭設置Connection字段指定為keep-alive,HTTP/1.0協議支持,但默認是關閉的,從HTTP/1.1以后,連接默認都是長連接。
在什么時候會超時?
- HTTP一般會有httpd守護進程,里面可以設置keep-alive timeout,當tcp連接閑置超過這個時間就會關閉,也可以在HTTP的header里面設置超時時間。
- TCP 的keep-alive包含三個參數,支持在系統內核的net.ipv4里面設置;當 TCP 連接之后,閑置了tcp_keepalive_time,則會發生偵測包,如果沒有收到對方的ACK,那么會每隔 tcp_keepalive_intvl 再發一次,直到發送了tcp_keepalive_probes,就會丟棄該連接。
tcp_keepalive_probes = 5
tcp_keepalive_time = 1800
8.HTTP 與 HTTPS 的區別
HTTP 即超文本傳輸協議,是一個基于TCP/IP通信協議來傳遞明文數據的協議。HTTP會存在這幾個問題:
- 請求信息是明文傳輸,容易被竊聽截取。
- 沒有驗證對方身份,存在被冒充的風險。
- 數據的完整性未校驗,容易被中間人篡改。
為了解決HTTP存在的問題,HTTPS出現啦。
HTTPS是什么?
HTTPS= HTTP+SSL/TLS,可以理解為 HTTPS 是身披 SSL(Secure Socket Layer,安全套接層)的HTTP。
它們的主要區別如下:
9.HTTPS的工作流程是怎樣的?
- HTTPS = HTTP + SSL/TLS,也就是用SSL/TLS對數據進行加密和解密,用HTTP進行傳輸。
- SSL,即Secure Sockets Layer(安全套接層協議),是網絡通信提供安全及數據完整性的一種安全協議。
- TLS,即Transport Layer Security(安全傳輸層協議),它是SSL3.0的后續版本。
- 客戶端發起HTTPS請求,連接到服務器的443端口。
- 服務器必須要有一套數字證書(證書內容有公鑰、證書頒發機構、失效日期等)。
- 服務器將自己的數字證書發送給客戶端(公鑰在證書里面,私鑰由服務器持有)。
- 客戶端收到數字證書之后,會驗證證書的合法性。如果證書驗證通過,就會生成一個隨機的對稱密鑰,用證書的公鑰加密。
- 客戶端將公鑰加密后的密鑰發送到服務器。
- 服務器接收到客戶端發來的密文密鑰之后,用自己之前保留的私鑰對其進行非對稱解密,解密之后就得到客戶端的密鑰,然后用客戶端密鑰對返回數據進行對稱加密,這樣子傳輸的數據都是密文啦。
- 服務器將加密后的密文返回到客戶端。
- 客戶端收到后,用自己的密鑰對其進行對稱解密,就能得到服務器返回的數據。
10.說說HTTP的狀態碼,301和302的區別?
- 301:永久重定向,表示所請求的資源已經永久地轉移到新的位置,這包含域名的改變或者是資源路徑的改變。
- 302:臨時重定向,表示所請求的資源臨時地轉移到新的位置,一般是24到48小時以內的轉移會用到302。
11.說說什么是數字簽名?什么是數字證書?
數字證書構成:
12.對稱加密和非對稱加密有什么區別
對稱加密:指加密和解密使用同一密鑰,優點是運算速度較快,缺點是不能安全地將密鑰傳輸給另一方。常見的對稱加密算法有:DES、AES等。
非對稱加密:指的是加密和解密使用不同的密鑰(即公鑰和私鑰)。公鑰與私鑰是成對存在的,如果用公鑰對數據進行加密,只有對應的私鑰才能解密。常見的非對稱加密算法有 RSA。
13.說說 DNS 的解析過程?
DNS的解析過程如下圖:
假設你要查詢www.baidu.com的IP地址:瀏覽器 -> 本地DNS服務器 -> 根域名服務器 -> 頂級域名服務器 -> 權威域名服務器
- 首先會查找瀏覽器的緩存,看看是否能找到www.baidu.com對應的IP地址,找到就直接返回;否則進行下一步。
- 將請求發往本地DNS服務器,如果查找到也直接返回,否則繼續進行下一步;
- 本地DNS服務器向根域名服務器發送請求,根域名服務器返回負責.com的頂級域名服務器的列表。
- 本地DNS服務器再向其中一個頂級域名服務器發送一個請求,返回負責.baidu的權威域名服務器的列表。
- 本地DNS服務器再向其中一個權威域名服務器發送一個請求,返回www.baidu.com所對應的IP地址。
14.說說 WebSocket與socket的區別
Socket是一套標準,它完成了對TCP/IP的高度封裝,屏蔽網絡細節,以便開發者更好地進行網絡編程。
Socket等于IP地址 + 端口 + 協議。
WebSocket是一個持久化的協議,它是伴隨H5而出的協議,用來解決HTTP不支持持久化連接的問題。
Socket是一個網絡編程的標準接口,而WebSocket則是應用層通信協議。
15.HTTP請求的過程與原理
HTTP是一個基于TCP/IP協議來傳遞數據的超文本傳輸協議,傳輸的數據類型有HTML、圖片等。
- 客戶端進行DNS域名解析,得到對應的IP地址
- 根據這個IP地址,找到對應的服務器建立TCP連接(三次握手)
- 建立TCP連接后發起HTTP請求(一個完整的http請求報文)
- 服務器響應HTTP請求,客戶端得到html代碼
- 客戶端解析html代碼,用html代碼中的資源(如 js、css、圖片等等)渲染頁面。
- 服務器關閉TCP連接(四次揮手)
16.forward和redirect的區別?
是servlet中的兩種主要跳轉方式。forward:轉發,redirect:重定向
從地址欄顯示來說
forward是服務器內部的重定向,服務器直接訪問目標地址,把里面的東西取出來,但是客戶端并不知道,因此用forward的話,客戶端瀏覽器的網址是不會發生變化的。
redirect是服務器根據邏輯,發送一個狀態碼,告訴瀏覽器重新去請求那個地址,所以地址欄顯示的是新地址。
從數據共享來說
由于在整個轉發的過程中使用的是同一個request,因此forward會將request信息帶到被重定向的jsp或servlet中使用,即可以共享數據。
redirect不能共享數據。
從運用的地方來說
forward一般用于用戶登錄時,根據角色轉發到相應的模塊
redirect一般用于用戶注銷登錄時返回主頁面
從本質上來說
forward轉發是服務器上的行為,redirect重定向是客戶端的行為。
從效率上來說
forword效率高,而redirect效率低。
從請求的次數來說
forword只有一次請求,而redirect有兩次請求。
17.Session和Cookie的區別
Cookie 是保存在客戶端的一小塊文本串的數據。客戶端向服務器發起請求時,服務器會向客戶端發送一個 Cookie,客戶端就把 Cookie 保存起來。下次向同一服務器再發起請求時,Cookie 就被攜帶發送到服務器。服務器可以根據這個 Cookie 判斷用戶的身份和狀態。
Session 指的是服務器和客戶端一次會話的過程。它是另一種記錄客戶端狀態的機制。不同的是 Cookie 是保存在客戶端瀏覽器中的,而 Session 是保存在服務器上的。客戶端瀏覽器在訪問服務器時,服務器會把客戶端信息以某種形式記錄在服務器上,這就是 Session。客戶端瀏覽器再次訪問時只需要從該 Session 中查找用戶的狀態。
Session 和 Cookie 到底有什么不同呢?
Session 和 Cookie 有什么關聯呢?
可以使用 Cookie 記錄 Session 的唯一標識
用戶第一次請求服務器時,服務器根據用戶提交的信息,創建對應的Session,請求返回時將此Session的唯一標識信息SessionID返回給瀏覽器,瀏覽器會將此SessionID信息存入Cookie中,同時Cookie記錄此SessionID是屬于哪個域名的。
當用戶第二次訪問服務器時,請求會自動判斷此域名下是否存在Cookie信息,如果存在,則自動將Cookie信息也發送給服務器,服務器會從Cookie中獲取SessionID,再根據 SessionID 查找對應的 Session 信息,如果沒有找到則說明用戶沒有登錄或者登錄失效,如果找到則證明用戶已經登錄可執行后面的操作。
分布式環境下 Session 該怎么處理呢?
分布式環境下,客戶端請求經過負載均衡,可能會分配到不同的服務器上,假如一個用戶的請求兩次沒有落到同一臺服務器上,那么在新的服務器上就沒有記錄該用戶狀態對應的 Session。
可以使用 Redis 等分布式緩存來存儲 Session,保證在多臺服務器間共享。
客戶端如果無法使用 Cookie 怎么辦呢?
有可能客戶端無法使用 Cookie,比如瀏覽器禁用 Cookie,或者客戶端是 安卓、IOS 設備等。
這時候怎么辦呢?SessionID 怎么存呢?怎么傳給服務器呢?
首先是 SessionID 的存儲,可以使用客戶端的本地存儲,比如瀏覽器的 sessionStorage。
接下來要怎么傳呢?
- 拼接到 URL:直接把 SessionID 作為 URL 的請求參數。
- 放到請求頭:把 SessionID 放到請求頭里面,比較常用。
18.詳細說一下 TCP 的三次握手機制
TCP 三次握手過程:
最開始,客戶端和服務端都處于 CLOSE(關閉)狀態,服務端監聽客戶端的請求,進入 LISTEN(監聽) 狀態。
客戶端發送連接請求,進行第一次握手(同步位 SYN=1,序號字段 seq=x),發送完畢后,客戶端就進入 SYN_SENT(同步已發送) 狀態。
服務端確認連接,進行第二次握手(同步位 SYN=1,確認位 ACK=1,序號字段 seq=y,確認號字段 ack=x+1), 發送完畢后,服務端就進入 SYN_RCV(同步已接收) 狀態。
客戶端收到服務端的確認后,再次向服務端確認,進行第三次握手(確認位 ACK=1,確認號字段 ack=y+1),發送完畢后,客戶端就進入 ESTABLISHED(連接已建立) 狀態,當服務端接收到這個包時,也進入 ESTABLISHED(連接已建立) 狀態。
需要C/C++ Linux服務器架構師學習資料加qun812855908獲取(資料包括C/C++,Linux,golang技術,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒體,CDN,P2P,K8S,Docker,TCP/IP,協程,DPDK,ffmpeg等),免費分享
19.TCP 握手為什么是三次,為什么不能是兩次?不能是四次?
為什么不能是兩次?
防止已失效的連接請求報文段突然又傳到服務端,因而產生錯誤
客戶端發送出去的第一個連接請求報文段并沒有丟失,而是因為某些未知原因在某個網絡節點上發生滯留,導致延遲到連接釋放以后的某個時間點才到達服務端。
本來這是一個早已失效的報文段,但是服務端收到此失效的報文段后,會誤認為這是客戶端再次發起的一個新的連接請求,于是服務端向客戶端又發出確認報文,表示同意建立連接。
如果不采用 “三次握手”,那么只要服務端發出確認報文后就會認為新的連接已經建立了,但是客戶端并沒有發出建立連接的請求,因此不會向服務端發送數據,服務端沒有收到數據就會一直等待,這樣服務端就會白白浪費掉很多資源。
所以我們需要 “第三次握手” 來確認這個過程:
通過第三次握手的數據來告訴服務端,客戶端有沒有收到服務端 “第二次握手” 時傳過去的數據,以及這個連接的序號是不是有效的。
若發送的這個數據是 “收到且沒有問題” 的信息,服務端接收后就可以正常建立 TCP 連接,否則建立 TCP 連接失敗,服務器關閉連接端口。由此減少服務器開銷和接收到失效請求時發生的錯誤。
為什么不是四次?
簡單來說,就是三次握手已經足夠創建可靠的連接,沒有必要再多一次握手導致花費更多的時間在建立連接上。
20.三次握手中每一次沒收到報文會發生什么情況?
第一次握手服務端未收到 SYN 報文
服務端不會進行任何的動作,而客戶端由于一段時間內沒有收到服務端發來的確認報文,等待一段時間后會重新發送 SYN 報文,
如果仍然沒有回應,會重復這個過程,直到發送次數超過最大重傳次數,就會返回連接建立失敗。
第二次握手客戶端未收到服務端響應的 ACK 報文
因為第二次握手是包含對客戶端第一次握手的 ACK 確認報文,所以如果客戶端遲遲沒有收到第二次握手,那么客戶端就會覺得可能是自己的 SYN 報文(第一次握手)丟失了,于是客戶端就會觸發超時重傳機制,重傳 SYN 報文。
然后,因為第二次握手是包含服務端的 SYN 報文,所以當客戶端收到后,需要給服務端發送 ACK 確認報文(第三次握手),服務端才會認為該 SYN 報文被客戶端收到了。
那么,如果第二次握手丟失了,服務端就收不到第三次握手,于是服務端這邊會觸發超時重傳機制,重傳 SYN-ACK 報文。
第三次握手服務端未收到客戶端發送過來的 ACK 報文
客戶端收到服務端的 SYN-ACK 報文后,就會給服務端發送一個 ACK 報文,也就是第三次握手,此時客戶端進入到 ESTABLISH(連接已建立) 狀態。
因為這個第三次握手的 ACK 是對第二次握手的 SYN 的確認報文,所以當第三次握手丟失了,如果服務端那一方遲遲收不到這個確認報文,就會觸發超時重傳機制,重傳 SYN-ACK 報文,直到收到第三次握手,或者達到最大重傳次數。
21.第二次握手傳回了 ACK,為什么還要傳回 SYN?
ACK 是為了告訴客戶端傳來的數據已經接收無誤。
而傳回 SYN 是為了告訴客戶端,服務端響應的確實是客戶端發送的報文。
22.第三次握手可以攜帶數據嗎?
第三次握手是可以攜帶數據的。
此時客戶端已經處于連接已建立狀態。對于客戶端來說,它已經建立連接成功了,并且確認服務端的接收和發送能力是正常的。
第一次握手不能攜帶數據是出于安全的考慮,因為如果允許攜帶數據,攻擊者每次在 SYN 報文中攜帶大量數據,就會導致服務端消耗更多的時間和空間去處理這些報文,會造成CPU和內存的消耗。
23.說說 TCP 四次揮手的過程?
- 數據傳輸結束后,通信雙方都可以主動發起斷開連接請求,這里假定客戶端發起。
- 客戶端發送釋放連接報文,進行第一次揮手(FIN=1,ACK=1,seq=u,ack=v),發送完畢后,客戶端進入 FIN_WAIT_1(終止等待1) 狀態。
- 服務端發送確認報文,進行第二次揮手(ACK=1,seq =v,ack=u+1),發送完畢后,服務端進入 CLOSE_WAIT(關閉等待) 狀態,客戶端收到這個確認包后,進入 FIN_WAIT_2(終止等待2) 狀態。
- 服務端發送釋放連接報文,進行第三次揮手(FIN=1,ACK1,seq=w,ack=u+1),發送完畢后,服務端進入LAST_ACK(最后確認) 狀態,等待來自客戶端的最后一個 ACK 報文。
- 客戶端發送確認報文,進行第四次揮手(ACK=1,seq=u+1,ack=w+1),客戶端收到來自服務端的關閉請求,發送一個確認包,并進入 TIME_WAIT(時間等待) 狀態,服務端接收到這個確認包后,關閉連接,進入 CLOSED(關閉) 狀態。
- 客戶端再經過 2MSL 后,也進入 CLOSED(關閉) 狀態。
客戶端在發送完最后一個確認報文后,為什么不直接進入關閉狀態 ? 而是要進入時間等待狀態,2MSL 后才進入關閉狀態,這是否有必要呢 ?
服務端發送TCP連接釋放報文段后進入最后確認狀態。
客戶端收到該報文段后,發送普通的TCP確認報文段,并進入關閉狀態而不是時間等待狀態。然而,該TCP確認報文段丟失了。
這必然會造成服務端對之前所發送的TCP連接釋放報文段的超時重傳,并仍處于最后確認狀態。重傳的TCP連接釋放報文段到達客戶端,由于客戶端處于關閉狀態,因此不理睬該報文段,這必然會造成服務端反復重傳TCP連接釋放報文段,并一直處于最后確認狀態而無法進入關閉狀態。
因此時間等待狀態以及處于該狀態2MSL時長,可以確保服務端可以收到最后一個TCP確認報文段而進入關閉狀態。
另外,客戶端在發送完最后一個TCP確認報文段后,再經過2MSL時長,就可以使本次連接持續時間內所產生的所有報文段都從網絡中消失,這樣就可以使下一個新的TCP連接中,不會出現舊連接中的報文段。
為什么等待時間是2MSL?
MSL 是報?最??存時間,它是任何報?在?絡上存在的最?時間,超過這個時間報?將被丟棄。
TIME_WAIT 等待 2 倍的 MSL,是因為?絡中可能存在來?發送?的數據包,當這些發送?的數據包被接收?處理后?會向對?發送響應,所以?來?回需要等待 2 倍的時間。
?如服務端如果沒有收到客戶端發送的TCP確認報文段,就會觸發超時重傳,重新發送TCP連接釋放報文段,客戶端收到后,會重發TCP確認報文段給服務端, ?來?去正好 2 個 MSL。
24.TCP 揮手為什么需要四次呢?
再來回顧下四次揮手雙方發 FIN 包的過程,就能理解為什么需要四次了。
關閉連接時,客戶端向服務端發送 FIN 報文,僅僅表示客戶端不再發送數據了但是還能接收數據。
服務端收到客戶端的 FIN 報文后,先返回一個 ACK 確認報文;而服務端可能還有數據需要處理和發送,等服務端不再發送數據了,再發送 FIN 報文給客戶端來表示同意現在關閉連接。
從上面的過程可知,服務端通常需要等待完成數據的發送和處理,所以服務端的 ACK 和 FIN 一般都會分開發送,從而導致比三次握手多了一次。
25.TCP 保活計時器有什么用?
除了時間等待計時器外,TCP 還有一個保活計時器(keepalive timer)。
設想這樣的場景:
TCP 雙方已經建立了連接,后來,客戶端的主機突然出現了故障。顯然,服務端以后就不能再收到客戶端發來的數據。因此,應當有措施使服務端不要再白白等待下去。這就需要使用保活計時器了。
服務端每收到一次客戶端的數據,就重新設置并啟動保活計時器(2小時定時)。若定時周期內都沒有收到客戶端發來的數據,服務端就發送一個探測報文段,以后每隔 75 秒鐘發送一次。若連續發送 10 個探測報文段后仍然無客戶端的響應,服務端就認為客戶端出了故障,接著就關閉這個連接。
26.CLOSE-WAIT 的狀態和意義?
服務端收到客戶端關閉連接的請求并確認之后,就會進入 CLOSE-WAIT 狀態。
此時服務端可能還有一些數據沒有傳輸完成,因此不能立即關閉連接,而 CLOSE-WAIT 狀態就是為了保證服務端在關閉連接之前將待發送的數據處理完。
27.說說 TCP 報文首部有哪些字段?
16位端口號:源端口號,標識發送該 TCP 報文段的應用進程;目的端口號,標識接收該 TCP 報文段的應用進程。
32位序號:指出本 TCP 報文段數據載荷的第一個字節的序號。32位序號:指出本 TCP 報文段數據載荷的第一個字節的序號。
32位確認號:指出期望收到對方下一個 TCP 報文段的數據載荷的第一個字節的序號,同時也是對之前收到的所有數據的確認。若確認號 = n,則表明到序號 n-1 為止的所有數據都已正確接收,期望收到序號為 n 的數據。
4位頭部長度:指出 TCP 報文段的首部長度。
6位標志位:
- 確認標志位ACK:取值為1時確認號字段才有效,取值為0時確認號字段無效。TCP 規定,在連接建立后所有傳送的 TCP 報文段都必須把 ACK 置為1。
- 同步標志位SYN:在 TCP 連接建立時用來同步序號。
- 終止標志位FIN:用來釋放 TCP 連接。
16位窗口大小:
- 指出發送本報文段的一方的接收窗口。
- 窗口值作為接收方讓發送方設置其發送窗口的依據。
- 這是以接收方的接收能力來控制發送方的發送能力,稱為流量控制。
- 發送窗口的大小還取決于擁塞窗口的大小,也就是應該從接收窗口和擁塞窗口中取小者。
16位校驗和:用來檢查整個 TCP 報文段在傳輸過程中是否出現了誤碼。
16位緊急指針:當發送方有緊急數據時,可將緊急數據插隊到發送緩存的最前面,并立刻封裝到一個 TCP 報文段中進行發送。緊急指針會指出本報文段的數據載荷部分包含了多長的緊急數據,緊急數據之后是普通數據。
28.TCP 是如何保證可靠性的?
TCP主要提供了 連接管理、校驗和、序列號/確認應答、流量控制、最大消息長度、超時重傳、擁塞控制等方式實現了可靠傳輸。
連接管理:TCP 使用三次握手和四次揮手來保證可靠地建立連接和釋放連接。
校驗和:用來檢查整個 TCP 報文段在傳輸過程中是否出現了誤碼。
序列號/確認應答:TCP 會給發送的每一個包進行編號,接收方會對收到的包進行應答,發送方就會知道接收方是否收到對應的包,如果發現沒有收到,就會重發,這樣就能保證數據的完整性了。
流量控制:TCP 連接的每一方都有固定大小的緩沖空間,TCP 的接收端只允許發送端發送接收端緩沖區能接納的數據大小。當接收方來不及處理發送方的數據時,能提示發送方降低發送的速率,防止包丟失。TCP 使用的流量控制協議是可變大小的滑動窗口協議。(TCP 利用滑動窗口實現流量控制)
最大消息長度:在建立 TCP 連接的時候,雙方約定一個最大的長度(MSS)作為發送的單位,重傳的時候也是以這個單位來進行重傳的。理想情況下是該長度的數據剛好不被網絡層分塊。
超時重傳:超時重傳是指發送出去的數據包到接收到確認包之間的時間,如果超過了這個時間,就會被認為是丟包了,需要重傳。
擁塞控制:如果網絡非常擁堵,此時再發送數據就會加重網絡負擔,那么發送的數據段很可能超過了最大生存時間也沒有到達接收方,就會產生丟包問題。為此 TCP 引入了慢啟動機制,先發出少量數據,就像探路一樣,先摸清當前的網絡擁堵狀態后,再決定按照多大的速度傳送數據。
29.說說 TCP 的流量控制?
TCP 提供了一種機制,可以讓發送方根據接收方的實際接收能力控制發送的數據量,這就是流量控制。
TCP 通過「滑動窗口」來實現流量控制
首先 TCP 雙方進行三次握手,初始化各自的窗口大小,均為 400 字節。
假如當前發送方給接收方發送了 200 字節,那么,發送方的SND.NXT會右移 200 字節,也就是說當前的可用窗口減少了 200 字節。
接收方收到后,放到緩沖隊列里面,REV.WND = 400-200=200 字節,所以 win=200 字節返回給發送方。接收方會在 ACK 的報文首部帶上縮小后的滑動窗口 200 字節
發送方又發送 200 字節過來,200 字節到達,繼續放到緩沖隊列里面。不過這時候,由于大量負載的原因,接收方處理不了這么多字節,只能處理 100 字節,剩余的 100 字節繼續放到緩沖隊列里面。這時候,REV.WND = 400-200-100=100 字節,即 win=100 字節返回給發送方。
發送方繼續發送 100 字節過來,這時候,接收窗口 win 變為 0。
發送方停止發送,開啟一個定時任務,每隔一段時間,就去詢問接收方,直到 win 大于 0,才開始繼續發送。
30.詳細說說 TCP 的滑動窗口?
TCP 發送一個數據,如果需要收到確認應答才會發送下一個數據。這樣的話就會有個缺點:效率會比較低。
為了解決這個問題,TCP 引入了滑動窗口,它是操作系統開辟的一個緩存空間。窗口大小表示無需等待確認應答而可以繼續發送數據的最大值。
TCP 頭部有個 16 位的窗口大小,它告訴對方本端的 TCP 接收緩沖區還能容納多少字節的數據,這樣對方就可以控制發送數據的速度,從而達到流量控制的目的。
通俗點講,就是接收方每次收到數據包,在發送確認報文的時候,同時告訴發送方,自己的接收緩沖區還有多少空閑空間,緩沖區的空閑空間,我們就稱之為接收窗口大小。
TCP 滑動窗口分為兩種: 發送窗口和接收窗口。
發送方的滑動窗口包含四個部分:
- 已發送且已收到 ACK 確認
- 已發送但未收到 ACK 確認
- 未發送但可以發送
- 未發送且不可發送
- 虛線矩形框,就是發送窗口。
- SND.WND:表示發送窗口的大小,上圖虛線框的格子數是 14 個,即發送窗口大小是 14。
- SND.NXT:下一個發送的位置,它指向未發送但可以發送的第一個字節的序列號。
- SND.UNA:一個絕對指針,它指向的是已發送但未收到確認的第一個字節的序列號。
接收方的滑動窗口包含三個部分:
- 已成功接收并確認
- 未收到數據但可以接收
- 未收到數據且不可以接收的數據
- 虛線矩形框,就是接收窗口。
- REV.WND:表示接收窗口的大小,上圖虛線框的格子數就是 9 個,即接收窗口的大小是 9。
- REV.NXT:下一個接收的位置,它指向未收到但可以接收的第一個字節的序列號。
31.說說 TCP 的擁塞控制?
什么是擁塞控制?不是有了流量控制嗎?
前?的流量控制是避免發送?的數據填滿接收?的緩存,但是并不知道整個?絡中發?了什么。
?般來說,計算機?絡都處在?個共享的環境。因此也有可能會因為其他主機之間的通信使得?絡出現擁堵。
在?絡出現擁堵時,如果繼續發送?量數據包,可能會導致數據包延遲、丟失等,這時 TCP 就會重傳數據,但是?重傳就會導致?絡的負擔更重,于是會導致更?的延遲以及更多的丟包,這個情況就會進?惡性循環并且被不斷地放?…
所以,TCP 不能忽略整個網絡中發?的事,它被設計成?個?私的協議,當?絡發送擁塞時,TCP 會?我犧牲,降低發送的數據流。
于是,就有了擁塞控制,擁塞控制的?的就是為了避免發送?的數據填滿整個?絡。
就像是一個水管,不能讓太多的水(數據流)流入水管,如果超過水管的承受能力,水管就會被撐爆(丟包)。
發送方維護一個擁塞窗口 cwnd(congestion window) 的變量,調節所要發送數據的量。
什么是擁塞窗??和發送窗?有什么關系呢?
擁塞窗? **cwnd **是發送?維護的?個狀態變量,它會根據?絡的擁塞程度動態變化。
發送窗? swnd 和接收窗? rwnd 是約等于的關系,那么由于加?了擁塞窗?的概念后,此時發送窗?的值 swnd = min(cwnd, rwnd),也就是取擁塞窗?和接收窗?中的最?值。
擁塞窗? cwnd 變化的規則:
- 只要?絡中沒有出現擁塞, cwnd 就會增?
- 但如果?絡中出現了擁塞, cwnd 就會減小
擁塞控制有哪些常用算法?
慢啟動
慢啟動算法,慢慢啟動。
它表示 TCP 建立連接完成后,一開始不要發送大量的數據,而是先探測一下網絡的擁塞程度。由小到大逐漸增加擁塞窗口的大小,如果沒有出現丟包,每收到一個 ACK,就將擁塞窗口 cwnd 的大小加 1(單位是 MSS)。每輪次發送窗口增加一倍,呈指數增長,如果出現丟包,擁塞窗口就減半,進入擁塞避免階段。
舉個例子:
- 連接建?完成后,?開始初始化 cwnd = 1 ,表示可以傳?個 MSS ??的數據。
- 當收到?個 ACK 確認應答后,cwnd 增加 1,于是?次性能夠發送 2 個。
- 當收到 2 個 ACK 確認應答后, cwnd 增加 2,于是就能?之前多發送 2 個,所以這?次能夠發送 4 個。
- 當這 4 個 ACK 確認到來的時候,每個確認 cwnd 增加 1, 4 個確認 cwnd 增加 4,于是就能?之前多發送 4 個,所以這?次能夠發送 8 個。
發送包的個數是呈指數性增?的。
為了防止 cwnd 增長過大而引起網絡擁塞,還需設置一個慢啟動閥值 ssthresh(slow start threshold)的狀態變量。當 cwnd 到達該閥值后,就好像水管被關小了水龍頭一樣,減少了擁塞狀態。即當 cwnd > ssthresh 時,進入擁塞避免算法。
擁塞避免
一般來說,慢啟動閥值 ssthresh 的大小是 65535 字節,cwnd 到達慢啟動閥值后
- 每收到一個 ACK 時,cwnd = cwnd + 1/cwnd
- 當每過一個 RTT 時,cwnd = cwnd + 1
顯然這是一個線性上升的算法,可以避免發送過快導致網絡出現擁塞問題。
接著上面慢啟動的例子,假定 ssthresh 為 8:
- 當 8 個 ACK 確認應答到來時,每個確認增加 1/8,8 個 ACK 確認后 cwnd ?共增加 1,于是這?次能夠發送 9 個 MSS ??的數據,變成了線性增?。
擁塞發生
當網絡擁塞發生丟包時,會有兩種情況:
- RTO 超時重傳
- 快速重傳
如果是發生了RTO 超時重傳,就會使用「擁塞發生」算法
- 慢啟動閥值 sshthresh = cwnd/2
- cwnd 重置為 1
- 進入新的慢啟動過程
這真的是辛辛苦苦幾十年,一朝回到解放前。其實還有更好的處理方式,就是「快速重傳」。當發送方收到 3 個連續的重復 ACK 時,就會快速地重傳,不必等待RTO超時再重傳。
發?「快速重傳」的擁塞發?算法:
- 擁塞窗口大小 cwnd = cwnd/2
- 慢啟動閥值 ssthresh = cwnd
- 進入快速恢復算法
快速恢復
快速重傳和快速恢復算法一般是同時使用的。快速恢復算法認為,還能收到 3 個重復的 ACK,說明網絡也沒有那么糟糕,所以沒必要像 RTO超時重傳 那樣強烈。
正如前面所說的,進入快速恢復之前,cwnd 和 sshthresh 已被更新:
- cwnd = cwnd/2
- sshthresh = cwnd
然后,真正進入「快速恢復」算法:
- cwnd = sshthresh + 3
- 重傳重復的那幾個 ACK(即丟失的那幾個數據包)
- 如果再收到重復的 ACK,那么 cwnd = cwnd +1
- 如果收到新數據的 ACK 后,cwnd = sshthresh。因為收到新數據的 ACK,表明恢復過程已經結束,可以再次進入「擁塞避免」算法了。
32.說說 TCP 的重傳機制?
重傳包括:超時重傳、快速重傳、帶選擇確認的重傳(SACK)、重復 SACK 四種。
超時重傳
超時重傳,是 TCP 協議保證數據可靠性的另一個重要機制,其原理是在發送某一個數據以后就開啟一個重傳計時器,在一定時間內如果沒有收到發送的數據報的 ACK 報文,那么就重新發送數據,直到收到 ACK 報文為止。
超時時間應該設置為多少合適呢?
RTT 就是數據完全發送完,到收到確認信號的時間,即數據包的一次往返時間。
超時重傳時間,就是 RTO(Retransmission Timeout)。那么,RTO 應該設置多大呢?
- 如果 RTO 設置很大,等了很久都沒重發,這樣肯定不行。
- 如果 RTO 設置很小,那很可能數據都沒有丟失,就開始重發了,這將會導致網絡阻塞,從而發生惡性循環,導致更多的超時出現。
一般來說,RTO 略微大于 RTT,效果是最佳的。
超時重傳并不是十分完美的重傳方案,它有這些缺點:
- 當一個報文丟失時,會等待一定的超時周期,才重傳分組,增加了端到端的時延。
- 當一個報文丟失時,在其等待超時的過程中,可能會出現這種情況:其后面的報文段已經被接收方接收了但卻遲遲得不到確認,發送方會認為其后面的報文段也丟失了,從而引起不必要的重傳,既浪費資源也浪費時間。
快速重傳
快速重傳可以用來解決超時重發的時間等待問題。
它不以時間驅動,而是以數據驅動。它是基于接收方的反饋信息來引發重傳的。
快速重傳的流程如下:
發送方發送了 1,2,3,4,5,6 份數據:
- 第一份 Seq=1 先送到了,于是 ACK 回2;
- 第二份 Seq=2 也送到了,于是 ACK 回3;
- 第三份 Seq=3 由于網絡等某些原因,沒送到;
- 第四份 Seq=4 送到了,但是由于 Seq=3 沒收到。因此 ACK 還是回3;
- 后面的 Seq=5,6 也送到了,ACK 還是回復3,因為 Seq=3 沒有收到。
- 發送方連續收到三個重復冗余的 ACK=3 的確認(其實是4個哈,但是因為前面的一個是正常的ACK,后面三個才是重復冗余的),于是知道哪個報文段在傳輸過程中丟失了;發送方就在重傳定時器過期之前,重傳該報文段。
- 最后,接收方收到了 Seq=3,此時因為 Seq=4,5,6 都收到了,于是它回 ACK=7。
快速重傳機制也有缺點:發送方并不知道到底是哪個報文丟失了,到底該重傳多少個數據包?
是只重傳 Seq=3 ?還是重傳 Seq=3、Seq=4、Seq=5、Seq=6 呢?因為發送方并不清楚這三個連續的 ACK=3 是誰傳回來的。
帶選擇確認的重傳(SACK)
為了解決應該重傳多少個包的問題? TCP 提供了帶選擇確認的重傳(即 SACK,Selective Acknowledgment)。
SACK 機制就是,在快速重傳的基礎上,接收方返回最近收到報文段的序列號范圍,這樣發送方就知道接收方哪些數據包是沒收到的。這樣就很清楚應該重傳哪些數據包。
如上圖中,發送?收到了三次同樣的 ACK 確認報?,于是就會觸發「快速重傳」機制,通過 SACK 信息發現只有 200~299 這段數據丟失,則重發時,就只選擇了這個 TCP 段進?重發。
重復 SACK(D-SACK)
D-SACK,英文是 Duplicate SACK,是在 SACK 的基礎上做了一些擴展,主要用來告訴發送方,有哪些數據包,自己重復接受了。
D-SACK 的目的是幫助發送方判斷,是否發生了包失序、ACK 丟失、包重復或偽重傳。讓 TCP 可以更好的做網絡流控。
例如 ACK 丟包導致的數據包重復:
- 接收?發給發送?的兩個 ACK 確認應答都丟失了,所以發送?超時后,重傳第?個數據包(3000 ~ 3499)
- 接收?發現數據是重復收到的,于是回了?個 SACK = 3000
3500,告訴「發送?」 30003500的數據早已被接收了,因為 ACK 都到 4000 了,意味著 4000 之前的所有數據都已經收到了,所以這個 SACK 就代表著 D-SACK 。這樣發送?就知道了,數據并沒有丟,而是接收?的 ACK 確認報?丟了。
33.說說 TCP 的粘包和拆包?
什么是 TCP 粘包和拆包?
TCP 是面向字節流,沒有界限的一串數據。TCP 底層并不了解上層業務數據的具體含義,它會根據 TCP 緩沖區的實際情況進行包的劃分,所以在業務上認為,一個完整的包可能會被 TCP 拆分成多個包進行發送,也有可能把多個小的包封裝成一個大的數據包進行發送,這就是所謂的 TCP 粘包和拆包問題。
為什么會產生粘包和拆包呢?
- 要發送的數據小于 TCP 發送緩沖區的大小,TCP 將多次寫入緩沖區的數據一次性發送出去,將會發生粘包;
- 接收方的應用層沒有及時讀取接收緩沖區的數據,將會發生粘包;
- 要發送的數據大于 TCP 發送緩沖區剩余空間的大小,將會發生拆包;
- 待發送的數據大于 MSS(最大報文長度),TCP 在傳輸前將會進行拆包。即 TCP報文長度 - TCP頭部長度 > MSS。
解決方案:
- 發送方給每個數據包添加包首部,首部中應該至少包含數據包的長度,這樣接收方在收到數據后,通過讀取包首部的長度字段,便知道每一個數據包的實際長度了。
- 發送方將每個數據包封裝為固定長度(不夠的可以通過補0填充),這樣接收方每次從接收緩沖區中讀取固定長度的數據,就自然而然的把每個數據包拆分開來。
- 可以在數據包之間設置邊界,如添加特殊符號,這樣接收方通過這個邊界就可以將不同的數據包拆分開來。
-
主機
+關注
關注
0文章
1009瀏覽量
35305 -
TCP
+關注
關注
8文章
1378瀏覽量
79298 -
UDP
+關注
關注
0文章
327瀏覽量
34039 -
數據鏈路
+關注
關注
0文章
26瀏覽量
8974
發布評論請先 登錄
相關推薦
評論