TCP、UDP、HTTP、HTTPS 一文足矣

一、簡介

TCP、UDP、HTTP、HTTPS 都是通信協(xié)議,也就是通信時所遵守的規(guī)則,只有雙方按照這個規(guī)則“說話”,對方才能理解或為之服務(wù)。

二、TCP、UDP、HTTP、HTTPS 之間的關(guān)系

TCP/IP 是個協(xié)議組,可分為四個層次:網(wǎng)絡(luò)接口層、網(wǎng)絡(luò)層、傳輸層和應(yīng)用層。

在網(wǎng)絡(luò)層,有 IP 協(xié)議、ICMP 協(xié)議、ARP 協(xié)議、RARP 協(xié)議等。
在傳輸層,有 TCP 協(xié)議與 UDP 協(xié)議。
在應(yīng)用層,有 WebSocket、FTP、HTTP、TELNET、SMTP、DNS 等協(xié)議。
而 HTTPS 可以理解為更安全的 HTTP 協(xié)議。

因此,TCP、UDP、HTTP、HTTPS 都是通信協(xié)議,只不過它們所在的層級不同,負(fù)責(zé)的工作也不同,并且 HTTP 是基于 TCP 實現(xiàn)的。

三、Socket 通信

Socket 是為了實現(xiàn)以上的通信過程而建立成來的通信管道,其真實的代表是客戶端和服務(wù)器端的一個通信進(jìn)程,雙方進(jìn)程通過 Socket 進(jìn)行通信,而通信的規(guī)則采用指定的協(xié)議。Socket 只是一種連接模式,不是協(xié)議。TCP、UDP,簡單的說(雖然不準(zhǔn)確)是兩個基本的協(xié)議,很多其它協(xié)議都是基于這兩個協(xié)議,如 HTTP 就是基于 TCP 的。用 Socket 可以創(chuàng)建 TCP 連接,也可以創(chuàng)建 UDP 連接,這意味著,用 Socket 可以創(chuàng)建任何協(xié)議的連接,因為其它協(xié)議都是基于此的。

四、TCP 協(xié)議

TCP 的建立連接協(xié)議又稱之為“三次握手”:

第一次握手:建立連接時,客戶端發(fā)送 SYN 包(syn=i)到服務(wù)器,并進(jìn)入 SYN_SEND 狀態(tài),等待服務(wù)器確認(rèn)。

第二次握手:服務(wù)器收到客戶端發(fā)來的 SYN 包,必須對客戶端進(jìn)行確認(rèn) ACK (ack=i+1),同時服務(wù)器也發(fā)送一個 SYN 包(syn=j)到客戶端,即服務(wù)器會發(fā)送 SYN+ACK 包,此時服務(wù)器進(jìn)入 SYN_RECV 狀態(tài)。

第三次握手:客戶端收到服務(wù)器發(fā)送的 SYN+ACK 包,向服務(wù)器發(fā)送確認(rèn)包 ACK(ack=j+1),此包發(fā)送完畢,客戶端和服務(wù)器進(jìn)入 ESTABLISHED 狀態(tài),完成三次握手。

TCP 三次握手

為什么需要“三次握手”

第一個原因:初始化 Seq,TCP 通信是有序的,通信雙方要通知對方自己的 Seq 值,也就是上圖中的 X 和 Y,這個值要作為之后數(shù)據(jù)通信的序號,以保證應(yīng)用層接受到數(shù)據(jù)不會因網(wǎng)絡(luò)延時等原因而亂序,TCP 會用 Seq 來拼接數(shù)據(jù)。

第二個原因:在謝希仁版《計算機(jī)網(wǎng)絡(luò)》第四版中講“三次握手”的目的是“為了防止已失效的連接請求報文段突然又傳送到了服務(wù)端,因而產(chǎn)生錯誤”。在另一部經(jīng)典的《計算機(jī)網(wǎng)絡(luò)》一書中講“三次握手”的目的是為了解決“網(wǎng)絡(luò)中存在延遲的重復(fù)分組”的問題。這兩種不同的表述其實闡明的是同一個問題。

謝希仁版《計算機(jī)網(wǎng)絡(luò)》中的例子是這樣的,“已失效的連接請求報文段”的產(chǎn)生在這樣一種情況下:Client 發(fā)出的第一個連接請求報文段并沒有丟失,而是在某個網(wǎng)絡(luò)結(jié)點長時間的滯留了,以致延誤到連接釋放以后的某個時間才到達(dá) Server。本來這是一個早已失效的報文段。但 Server 收到此失效的連接請求報文段后,就誤認(rèn)為是 Client 再次發(fā)出的一個新的連接請求。于是就向 Client 發(fā)出確認(rèn)報文段,同意建立連接。

假設(shè)不采用“三次握手”,那么只要 Server 發(fā)出確認(rèn),新的連接就建立了。由于現(xiàn)在 Client 并沒有發(fā)出建立連接的請求,因此不會理睬 Server 的確認(rèn),也不會向 Server 發(fā)送數(shù)據(jù)。但 Server 卻以為新的運輸連接已經(jīng)建立,并一直等待 Client 發(fā)來數(shù)據(jù)。這樣,Server 的很多資源就白白浪費掉了。

“四次揮手”過程

由于 TCP 連接是全雙工的,因此每個方向都必須單獨進(jìn)行關(guān)閉。這原則是當(dāng)一方完成它的數(shù)據(jù)發(fā)送任務(wù)后就能發(fā)送一個 FIN 來終止這個方向的連接。收到一個 FIN 只意味著這一方向上沒有數(shù)據(jù)流動,而對方仍能發(fā)送數(shù)據(jù)。首先進(jìn)行關(guān)閉的一方將執(zhí)行主動關(guān)閉,而另一方執(zhí)行被動關(guān)閉。

  1. TCP 客戶端發(fā)送一個 FIN,用來關(guān)閉客戶到服務(wù)器的數(shù)據(jù)傳送。
  2. 服務(wù)器收到這個 FIN,發(fā)回一個 ACK,確認(rèn)序號為收到的序號加 1。和 SYN 一樣,一個 FIN 將占用一個序號。
  3. 服務(wù)器關(guān)閉客戶端的連接,發(fā)送一個 FIN 給客戶端。
  4. 客戶段發(fā)回 ACK 報文確認(rèn),并將確認(rèn)序號設(shè)置為收到序號加1。
TCP四次揮手

為什么需要“四次揮手”

那可能有人會有疑問,在 TCP 連接握手時為何 ACK 是和 SYN 一起發(fā)送,這里 ACK 卻沒有和 FIN 一起發(fā)送呢?

原因是因為 TCP 是全雙工模式,接收到 FIN 時意味將沒有數(shù)據(jù)再發(fā)來,但是還是可以繼續(xù)發(fā)送數(shù)據(jù)。同時發(fā)送雙方都需要發(fā)送 FIN 報文和 ACK 報文,加起來就是四次了。

TIME_WAIT 狀態(tài)
在四次揮手的最后一次揮手中,主動斷開方在發(fā)送最后一個 ACK 后,不能立刻關(guān)閉,而是需要等待 2MSL 后才能關(guān)閉,這是為什么呢?同時這也是面試中常提到的一個問題。原因如下:

假設(shè)發(fā)起主動關(guān)閉的一方(Client)最后發(fā)送的 ACK 在網(wǎng)絡(luò)中丟失,由于 TCP 協(xié)議的重傳機(jī)制,被動關(guān)閉的一方將會重發(fā) FIN,在該 FIN 到達(dá) Client之前,Client 必須維護(hù)這條連接狀態(tài),也就說這條 TCP 連接所對應(yīng)的資源不能被立即釋放或重新分配,直到另一方重發(fā)的 FIN 達(dá)到之后,Client 重發(fā) ACK 后,經(jīng)過 2MSL 時間周期沒有再收到另一方的 FIN 之后,該 TCP 連接才能 CLOSED。

如果主動關(guān)閉一方不維護(hù)這樣一個 TIME_WAIT 狀態(tài),那么當(dāng)被動關(guān)閉一方重發(fā)的 FIN 到達(dá)時,主動關(guān)閉一方的 TCP 傳輸層會用 RST 包響應(yīng)對方,這會被對方認(rèn)為是有錯誤發(fā)生,然而這事實上只是正常的關(guān)閉連接過程,并非異常。

TCP 粘包拆包
TCP是基于字節(jié)流的,雖然應(yīng)用層和 TCP 傳輸層之間的數(shù)據(jù)交互是大小不等的數(shù)據(jù)塊,但是 TCP 把這些數(shù)據(jù)塊僅僅看成一連串無結(jié)構(gòu)的字節(jié)流,沒有邊界;另外從 TCP 的幀結(jié)構(gòu)也可以看出,在 TCP 的首部沒有表示數(shù)據(jù)長度的字段,基于上面兩點,在使用TCP傳輸數(shù)據(jù)時,才有粘包或者拆包現(xiàn)象發(fā)生的可能。

粘包、拆包發(fā)生原因
發(fā)生TCP粘包或拆包有很多原因,現(xiàn)列出常見的幾點:

  1. 要發(fā)送的數(shù)據(jù)大于TCP發(fā)送緩沖區(qū)剩余空間大小,將會發(fā)生拆包。
  2. 待發(fā)送數(shù)據(jù)大于MSS(最大報文長度),TCP在傳輸前將進(jìn)行拆包。
  3. 要發(fā)送的數(shù)據(jù)小于TCP發(fā)送緩沖區(qū)的大小,TCP將多次寫入緩沖區(qū)的數(shù)據(jù)一次發(fā)送出去,將會發(fā)生粘包。
  4. 接收數(shù)據(jù)端的應(yīng)用層沒有及時讀取接收緩沖區(qū)中的數(shù)據(jù),將發(fā)生粘包。
粘包拆包

粘包、拆包解決辦法
通過以上分析,我們清楚了粘包或拆包發(fā)生的原因,那么如何解決這個問題呢?解決問題的關(guān)鍵在于如何給每個數(shù)據(jù)包添加邊界信息,常用的方法有如下幾個:

1、發(fā)送端給每個數(shù)據(jù)包添加包首部,首部中應(yīng)該至少包含數(shù)據(jù)包的長度,這樣接收端在接收到數(shù)據(jù)后,通過讀取包首部的長度字段,便知道每一個數(shù)據(jù)包的實際長度了。

2、發(fā)送端將每個數(shù)據(jù)包封裝為固定長度(不夠的可以通過補0填充),這樣接收端每次從接收緩沖區(qū)中讀取固定長度的數(shù)據(jù)就自然而然的把每個數(shù)據(jù)包拆分開來。

3、可以在數(shù)據(jù)包之間設(shè)置邊界,如添加特殊符號,這樣,接收端通過這個邊界就可以將不同的數(shù)據(jù)包拆分開。

那么 UDP 是否會發(fā)生粘包或拆包的現(xiàn)象呢?
答案是:不會。UDP 是基于報文發(fā)送的,從 UDP 的幀結(jié)構(gòu)可以看出,在 UDP 首部采用了 16bit 來指示 UDP 數(shù)據(jù)報文的長度,因此在應(yīng)用層能很好的將不同的數(shù)據(jù)報文區(qū)分開,從而避免粘包和拆包的問題。

五、什么是HTTP協(xié)議

HTTP 全稱是 HyperText Transfer Protocal,即:超文本傳輸協(xié)議。從1990 年開始就在 WWW 上廣泛應(yīng)用,是現(xiàn)今在 WWW 上應(yīng)用最多的協(xié)議。HTTP 是應(yīng)用層協(xié)議,當(dāng)你上網(wǎng)瀏覽網(wǎng)頁的時候,瀏覽器和 Web 服務(wù)器之間就會通過 HTTP 在 Internet 上進(jìn)行數(shù)據(jù)的發(fā)送和接收。HTTP 是一個基于請求/響應(yīng)模式的、無狀態(tài)的協(xié)議,即我們通常所說的 Request/Response。

先看看請求(Request)報文:

HTTP_Request

請求(Request)報文 = 請求行 + 請求頭 + 空行 + 請求體

請求行中包含請求方法,常見的請求方法有:

GET:獲取資源,當(dāng)前網(wǎng)絡(luò)請求中,絕大部分使用的是 GET 方法。

POST:傳輸實體主體,POST 主要用來傳輸數(shù)據(jù),而 GET 主要用來獲取資源。

PUT:上傳文件,由于自身不帶驗證機(jī)制,任何人都可以上傳文件,因此存在安全性問題,一般不使用該方法。

DELETE:刪除文件,與 PUT 功能相反,并且同樣不帶驗證機(jī)制。

HEAD:獲取報文首部,和 GET 方法類似,但是不返回報文實體主體部分。主要用于確認(rèn) URL 的有效性以及資源更新的日期時間等。

HTTP_Response

響應(yīng)(Response)報文 = 狀態(tài)行 + 響應(yīng)頭 + 空行 + 響應(yīng)體

其中,狀態(tài)行包含響應(yīng)的狀態(tài),常見的狀態(tài)如下:

1XX 信息

  • 100 Continue :表明到目前為止都很正常,客戶端可以繼續(xù)發(fā)送請求或者忽略這個響應(yīng)。

2XX 成功

  • 200 OK

  • 204 No Content :請求已經(jīng)成功處理,但是返回的響應(yīng)報文不包含實體的主體部分。一般在只需要從客戶端往服務(wù)器發(fā)送信息,而不需要返回數(shù)據(jù)時使用。

  • 206 Partial Content :表示客戶端進(jìn)行了范圍請求,響應(yīng)報文包含由 Content-Range 指定范圍的實體內(nèi)容。

3XX 重定向

  • 301 Moved Permanently :永久性重定向

  • 302 Found :臨時性重定向

  • 303 See Other :和 302 有著相同的功能,但是 303 明確要求客戶端應(yīng)該采用 GET 方法獲取資源。

  • 注:雖然 HTTP 協(xié)議規(guī)定 301、302 狀態(tài)下重定向時不允許把 POST 方法改成 GET 方法,但是大多數(shù)瀏覽器都會在 301、302 和 303 狀態(tài)下的重定向把 POST 方法改成 GET 方法。

  • 304 Not Modified :如果請求報文首部包含一些條件,例如:If-Match,If-Modified-Since,If-None-Match,If-Range,If-Unmodified-Since,如果不滿足條件,則服務(wù)器會返回 304 狀態(tài)碼。

  • 307 Temporary Redirect :臨時重定向,與 302 的含義類似,但是 307 要求瀏覽器不會把重定向請求的 POST 方法改成 GET 方法。

4XX 客戶端錯誤

  • 400 Bad Request :請求報文中存在語法錯誤。

  • 401 Unauthorized :該狀態(tài)碼表示發(fā)送的請求需要有認(rèn)證信息(BASIC 認(rèn)證、DIGEST 認(rèn)證)。如果之前已進(jìn)行過一次請求,則表示用戶認(rèn)證失敗。

  • 403 Forbidden :請求被拒絕。

  • 404 Not Found

5XX 服務(wù)器錯誤

  • 500 Internal Server Error :服務(wù)器正在執(zhí)行請求時發(fā)生錯誤。

  • 503 Service Unavailable :服務(wù)器暫時處于超負(fù)載或正在進(jìn)行停機(jī)維護(hù),現(xiàn)在無法處理請求。

HTTP 通信機(jī)制是在一次完整的 HTTP 通信過程中,Web 瀏覽器與 Web 服務(wù)器之間將完成下列7個步驟:

  1. 建立 TCP 連接
    在 HTTP 工作開始之前,Web 瀏覽器首先要通過網(wǎng)絡(luò)與 Web 服務(wù)器建立連接,該連接是通過 TCP 來完成的,該協(xié)議與 IP 協(xié)議共同構(gòu)建 Internet,即著名的 TCP/IP 協(xié)議族,因此 Internet 又被稱作是 TCP/IP 網(wǎng)絡(luò)。HTTP 是比 TCP 更高層次的應(yīng)用層協(xié)議,根據(jù)規(guī)則,只有低層協(xié)議建立之后才能,才能進(jìn)行更層協(xié)議的連接,因此,首先要建立 TCP 連接,一般 TCP 連接的端口號是 80
  2. Web 瀏覽器向 Web 服務(wù)器發(fā)送請求命令
    一旦建立了TCP連接,Web瀏覽器就會向Web服務(wù)器發(fā)送請求命令。例如:GET/sample/hello.jsp HTTP/1.1
  3. Web 瀏覽器發(fā)送請求頭信息
    瀏覽器發(fā)送其請求命令之后,還要以頭信息的形式向 Web 服務(wù)器發(fā)送一些別的信息,之后瀏覽器發(fā)送了一空白行來通知服務(wù)器,它已經(jīng)結(jié)束了該頭信息的發(fā)送。
  4. Web 服務(wù)器應(yīng)答
    客戶機(jī)向服務(wù)器發(fā)出請求后,服務(wù)器會客戶機(jī)回送應(yīng)答,HTTP/1.1 200 OK,應(yīng)答的第一部分是協(xié)議的版本號和應(yīng)答狀態(tài)碼
  5. Web 服務(wù)器發(fā)送應(yīng)答頭信息
    正如客戶端會隨同請求發(fā)送關(guān)于自身的信息一樣,服務(wù)器也會隨同應(yīng)答向用戶發(fā)送關(guān)于它自己的數(shù)據(jù)及被請求的文檔。
  6. Web 服務(wù)器向瀏覽器發(fā)送數(shù)據(jù)
    Web 服務(wù)器向瀏覽器發(fā)送頭信息后,它會發(fā)送一個空白行來表示頭信息的發(fā)送到此為結(jié)束,接著,它就以 Content-Type 應(yīng)答頭信息所描述的格式發(fā)送用戶所請求的實際數(shù)據(jù)
  7. Web 服務(wù)器關(guān)閉 TCP 連接
    一般情況下,一旦 Web 服務(wù)器向瀏覽器發(fā)送了請求數(shù)據(jù),它就要關(guān)閉 TCP 連接,然后如果瀏覽器或者服務(wù)器在其頭信息加入了這行Connection:keep-alive,TCP 連接在發(fā)送后將仍然保持打開狀態(tài),于是,瀏覽器可以繼續(xù)通過相同的連接發(fā)送請求。保持連接節(jié)省了為每個請求建立新連接所需的時間,還節(jié)約了網(wǎng)絡(luò)帶寬。

六、HTTPS 的工作原理

HTTPS 在傳輸數(shù)據(jù)之前需要客戶端(瀏覽器)與服務(wù)端(網(wǎng)站)之間進(jìn)行一次握手,在握手過程中將確立雙方加密傳輸數(shù)據(jù)的密碼信息。TLS/SSL 協(xié)議不僅僅是一套加密傳輸?shù)膮f(xié)議,更是一件經(jīng)過藝術(shù)家精心設(shè)計的藝術(shù)品,TLS/SSL 中使用了非對稱加密、對稱加密以及 HASH 算法。握手過程的具體描述如下:

  1. 瀏覽器將自己支持的一套加密規(guī)則發(fā)送給網(wǎng)站。
  2. 網(wǎng)站從中選出一組加密算法與 HASH 算法,并將自己的身份信息以證書的形式發(fā)回給瀏覽器。證書里面包含了網(wǎng)站地址,加密公鑰,以及證書的頒發(fā)機(jī)構(gòu)等信息。
  3. 瀏覽器獲得網(wǎng)站證書之后瀏覽器要做以下工作:
    a) 驗證證書的合法性(頒發(fā)證書的機(jī)構(gòu)是否合法,證書中包含的網(wǎng)站地址是否與正在訪問的地址一致等),如果證書受信任,則瀏覽器欄里面會顯示一個小鎖頭,否則會給出證書不受信的提示。
    b) 如果證書受信任,或者是用戶接受了不受信的證書,瀏覽器會生成一串隨機(jī)數(shù)的密碼,并用證書中提供的公鑰加密。
    c) 使用約定好的 HASH 算法計算握手消息,并使用生成的隨機(jī)數(shù)對消息進(jìn)行加密,最后將之前生成的所有信息發(fā)送給網(wǎng)站。
  4. 網(wǎng)站接收瀏覽器發(fā)來的數(shù)據(jù)之后要做以下的操作:
    a) 使用自己的私鑰將信息解密取出密碼,使用密碼解密瀏覽器發(fā)來的握手消息,并驗證 HASH 是否與瀏覽器發(fā)來的一致。
    b) 使用密碼加密一段握手消息,發(fā)送給瀏覽器。
  5. 瀏覽器解密并計算握手消息的 HASH,如果與服務(wù)端發(fā)來的 HASH 一致,此時握手過程結(jié)束,之后所有的通信數(shù)據(jù)將由之前瀏覽器生成的隨機(jī)密碼并利用對稱加密算法進(jìn)行加密。
HTTPS 通信過程

簡單的說:HTTPS 使用對稱加密的方法通信,秘鑰為 Key。但是為了安全的把秘鑰 Key 發(fā)送給對方,于是在通信前,使用非對稱加密的方法加密 Key。

這樣做的目的是:非對稱加密的安全性更強,但是加解密過程復(fù)雜耗時,對稱加密的加解密過程簡單,但安全性不強,于是 HTTPS 綜合兩種加密方式,既保證了安全性,又保證了效率。

HTTPS協(xié)議和HTTP協(xié)議的區(qū)別:

  1. HTTPS 協(xié)議需要到 ca 申請證書,一般免費證書很少,需要交費。
  2. HTTP 是超文本傳輸協(xié)議,信息是明文傳輸,HTTPS 則是具有安全性的 SSL 加密傳輸協(xié)議。
  3. HTTP和HTTPS使用的是完全不同的連接方式用的端口也不一樣,前者是 80,后者是 443。
  4. HTTP 的連接很簡單,是無狀態(tài)的 。
  5. HTTPS 協(xié)議是由 SSL+HTTP 協(xié)議構(gòu)建的可進(jìn)行加密傳輸、身份認(rèn)證的網(wǎng)絡(luò)協(xié)議,要比 HTTP 協(xié)議安全。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容