網路協議中HTTP,TCP,UDP,Socket,WebSocket的優缺點/區別

来源:https://www.cnblogs.com/lcr-smg/archive/2018/12/15/10122863.html
-Advertisement-
Play Games

先說一下網路的層級:由下往上分為 物理層、數據鏈路層、網路層、傳輸層、會話層、表示層和應用層 1、TCP和UDP TCP:是面向連接的一種傳輸控制協議。屬於傳輸層協議。TCP連接之後,客戶端和伺服器可以互相發送和接收消息,在客戶端或者伺服器沒有主動斷開之前,連接一直存在屬於長連接。 優點:安全、傳輸 ...


先說一下網路的層級:由下往上分為 物理層、數據鏈路層、網路層、傳輸層、會話層、表示層和應用層

1、TCP和UDP

TCP:是面向連接的一種傳輸控制協議。屬於傳輸層協議。TCP連接之後,客戶端和伺服器可以互相發送和接收消息,在客戶端或者伺服器沒有主動斷開之前,連接一直存在屬於長連接。

優點:安全、傳輸數據無大小限制、準確可靠,先發先至

缺點:效率低,不能做離線任務、連接有耗時

UDP:是面向非連接的用戶數據報協議。屬於傳輸層協議。所謂的無連接就是在傳輸數據之前不需要交換信息,沒有握手建立連接的過程,只需要直接將對應的數據發送到指定的地址和埠就行。

例:我不管你要不要,我就一直發給你。就好比QQ消息一樣,當你離線的時候仍然可以收到消息

優點:可以傳輸大文件,速度快,效率高

缺點:不安全,容易丟包(數據)、先發未必先至

補充:

TCP協議建立需要三次握手,斷開連接需要四次揮手

第一次握手:客戶端發送syn包(syn=j)到伺服器,併進入SYN_SEND狀態,等待伺服器確認;

第二次握手:伺服器收到syn包,必須確認客戶的SYN(ack=j+1),同時自己也發送一個SYN包(syn=k),即SYN+ACK包,此時伺服器進入SYN_RECV狀態;

第三次握手:客戶端收到伺服器的SYN+ACK包,向伺服器發送確認包ACK(ack=k+1),此包發送完畢,客戶端和伺服器進入ESTABLISHED狀態,完成三次握手。

為什麼需要三次握手:避免丟包(數據丟失)

 

   握手過程中傳送的包里不包含數據,三次握手完畢後,客戶端與伺服器才正式開始傳送數據

       斷開連接時伺服器和客戶端均可以主動發起斷開TCP連接的請求,斷開過程需要經過“四次握手”

因為當A給B發送消息時,只有B同意了才能傳輸。由此可以看出HTTP協議是基於TCP的。因為當你在向後臺請求數據的時候,後臺必須同意,你才可以請求,否則都是白扯

2、HTTP

HTTP是基於TCP協議的應用的超文本傳輸協議,屬於應用層的協議。請求時需建立TCP連接,請求結束後斷開連接,完成一次請求/響應操作。

HTTP協議永遠都是客戶端發起請求,伺服器回送響應,這樣就限制了使用HTTP協議,無法實現在客戶端沒有發起請求的時候,伺服器將消息推送給客戶端。

HTTP協議是一個無狀態的協議,同一個客戶端的這次請求和上次請求是沒有對應關係。

優點:基於應用級的介面使用方便

缺點:(1)傳輸速度慢,數據包大。(2)如實現實時交互,伺服器性能壓力大。(3)數據傳輸安全性差

註意:伺服器不會主動給客戶端發送數據。

3、Socket

Socket是對TCP/IP協議的封裝,Socket本身並不是協議,而是一個調用介面(API)

Socket連接需要一對套接字,一個運行於客戶端,另一個運行於服務端!之間的連接分為三個步驟:伺服器監聽,客戶端請求,連接確認

(1)伺服器監聽:是服務端套接字並不定位具體的客戶端套接字,而是處於等待連接的狀態,實時監控網路狀態。

(2)客戶端請求:是由客戶端的套接字提出連接請求,要連接的目標是服務端的套接字。所以客戶端的套接字必須首先描述它要連接的伺服器的套接字,指出伺服器端套接字的地址和埠號,然後就向伺服器端套接字提出連接請求。

(3)連接確認:是指當伺服器端套接字監聽到或者說接收到客戶端套接字的連接請求,它就響應客戶端套接字的請求,建立一個新的線程,把伺服器端套接字的描述發給客戶端,一旦客戶端確認了此描述,連接就建立好了。而伺服器端套接字繼續處於監聽狀態,繼續接收其他客戶端套接字的連接請求。

4、WebSocket

雖然叫WebSocket,但它與Socket沒有任何關係。就好比:Java與JavaScript,雷鋒與雷峰塔,印度與印度尼西亞,黑客與博客的關係,兩者沒有任何關係!

WebSocket也是一種協議,並且也是基於TCP協議的。可以理解為WebSocket是HTTP的優化,但WebSocket不僅僅在Web應用程式上得到支持。

WebSocket雖然是Html5的產物,但也不僅僅局限於瀏覽器的應用程式,許多語言都提供了WebSocket的支持,比如C,C++,Python等

webSocket概念:

    在WebSocket概念出來之前,如果頁面要不停地顯示最新的價格,那麼必須不停地刷新頁面,或者用一段js代碼每隔幾秒鐘發消息詢問伺服器數據。
    而使用WebSocket技術之後,當伺服器有了新的數據,會主動通知瀏覽器。 如當服務端有新的比特幣價格之後,瀏覽器立馬接收到消息。

webSocket優點:

    1. 節約帶寬。不停地輪詢服務端數據這種方式,使用的是http協議,head信息很大,有效數據占比低, 而使用WebSocket方式,頭信息很小,有效數據占比高。
    2. 無浪費。 輪詢方式有可能輪詢10次,才碰到服務端數據更新,那麼前9次都白輪詢了,因為沒有拿到變化的數據。 而WebSocket是由伺服器主動回發,來的都是新數據。
    3. 實時性,考慮到伺服器壓力,使用輪詢方式不可能很短的時間間隔,否則伺服器壓力太多,所以輪詢時間間隔都比較長,好幾秒,設置十幾秒。 而WebSocket是由伺服器主動推送過來,實時性是最高的。

Websocket的作用
在講Websocket之前,我就順帶著講下 long poll 和 ajax輪詢 的原理。

ajax輪詢
首先是 ajax輪詢 ,ajax輪詢 的原理非常簡單,讓瀏覽器隔個幾秒就發送一次請求,詢問伺服器是否有新信息。
場景再現:
客戶端:啦啦啦,有沒有新信息(Request)
服務端:沒有(Response)
客戶端:啦啦啦,有沒有新信息(Request)
服務端:沒有。。(Response)
客戶端:啦啦啦,有沒有新信息(Request)
服務端:你好煩啊,沒有啊。。(Response)
客戶端:啦啦啦,有沒有新消息(Request)
服務端:好啦好啦,有啦給你。(Response)
客戶端:啦啦啦,有沒有新消息(Request)
服務端:。。。。。沒。。。。沒。。。沒有(Response) ---- loop

long poll 
long poll 其實原理跟 ajax輪詢 差不多,都是採用輪詢的方式,不過採取的是阻塞模型(一直打電話,沒收到就不掛電話),也就是說,客戶端發起連接後,如果沒消息,就一直不返回Response給客戶端。直到有消息才返回,返回完之後,客戶端再次建立連接,周而複始。
場景再現
客戶端:啦啦啦,有沒有新信息,沒有的話就等有了才返回給我吧(Request)
服務端:額。。 等待到有消息的時候。。來 給你(Response)
客戶端:啦啦啦,有沒有新信息,沒有的話就等有了才返回給我吧(Request) -loop

從上面可以看出其實這兩種方式,都是在不斷地建立HTTP連接,然後等待服務端處理,可以體現HTTP協議的另外一個特點,被動性
何為被動性呢,其實就是,服務端不能主動聯繫客戶端,只能有客戶端發起。
簡單地說就是,伺服器是一個很懶的冰箱(這是個梗)(不會、不能主動發起連接),但是上司有命令,如果有客戶來,不管多麼累都要好好接待。

說完這個,我們再來說一說上面的缺陷(原諒我廢話這麼多吧OAQ)
從上面很容易看出來,不管怎麼樣,上面這兩種都是非常消耗資源的。
ajax輪詢 需要伺服器有很快的處理速度和資源。(速度)
long poll 需要有很高的併發,也就是說同時接待客戶的能力。(場地大小)
所以ajax輪詢 和long poll 都有可能發生這種情況。

客戶端:啦啦啦啦,有新信息麽?
服務端:月線正忙,請稍後再試(503 Server Unavailable)
客戶端:。。。。好吧,啦啦啦,有新信息麽?
服務端:月線正忙,請稍後再試(503 Server Unavailable)

--------------------------
言歸正傳,我們來說Websocket吧
通過上面這個例子,我們可以看出,這兩種方式都不是最好的方式,需要很多資源。
一種需要更快的速度,一種需要更多的'電話'。這兩種都會導致'電話'的需求越來越高。
哦對了,忘記說了HTTP還是一個無狀態協議。(感謝評論區的各位指出OAQ)
通俗的說就是,伺服器因為每天要接待太多客戶了,是個健忘鬼,你一掛電話,他就把你的東西全忘光了,把你的東西全丟掉了。你第二次還得再告訴伺服器一遍。

所以在這種情況下出現了,Websocket出現了。
他解決了HTTP的這幾個難題。
首先,被動性,當伺服器完成協議升級後(HTTP->Websocket),服務端就可以主動推送信息給客戶端啦。
所以上面的情景可以做如下修改。
客戶端:啦啦啦,我要建立Websocket協議,需要的服務:chat,Websocket協議版本:17(HTTP Request)
服務端:ok,確認,已升級為Websocket協議(HTTP Protocols Switched)
客戶端:麻煩你有信息的時候推送給我噢。。
服務端:ok,有的時候會告訴你的。
服務端:balabalabalabala
服務端:balabalabalabala
服務端:哈哈哈哈哈啊哈哈哈哈
服務端:笑死我了哈哈哈哈哈哈哈

就變成了這樣,只需要經過一次HTTP請求,就可以做到源源不斷的信息傳送了。(在程式設計中,這種設計叫做回調,即:你有信息了再來通知我,而不是我傻乎乎的每次跑來問你)
這樣的協議解決了上面同步有延遲,而且還非常消耗資源的這種情況。


那麼為什麼他會解決伺服器上消耗資源的問題呢?


其實我們所用的程式是要經過兩層代理的,即HTTP協議在Nginx等伺服器的解析下,然後再傳送給相應的Handler(PHP等)來處理。
簡單地說,我們有一個非常快速的接線員(Nginx),他負責把問題轉交給相應的客服(Handler)
本身接線員基本上速度是足夠的,但是每次都卡在客服(Handler)了,老有客服處理速度太慢。,導致客服不夠。
Websocket就解決了這樣一個難題,建立後,可以直接跟接線員建立持久連接,有信息的時候客服想辦法通知接線員,然後接線員在統一轉交給客戶。
這樣就可以解決客服處理速度過慢的問題了。

同時,在傳統的方式上,要不斷的建立,關閉HTTP協議,由於HTTP是非狀態性的,每次都要重新傳輸identity info(鑒別信息),來告訴服務端你是誰。
雖然接線員很快速,但是每次都要聽這麼一堆,效率也會有所下降的,同時還得不斷把這些信息轉交給客服,不但浪費客服的處理時間,而且還會在網路傳輸中消耗過多的流量/時間。
但是Websocket只需要一次HTTP握手,所以說整個通訊過程是建立在一次連接/狀態中,也就避免了HTTP的非狀態性,服務端會一直知道你的信息,直到你關閉請求,這樣就解決了接線員要反覆解析HTTP協議,還要查看identity info的信息。
同時由客戶主動詢問,轉換為伺服器(推送)有信息的時候就發送(當然客戶端還是等主動發送信息過來的。。),沒有信息的時候就交給接線員(Nginx),不需要占用本身速度就慢的客服(Handler)了。
 
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1. 請用至少3中方式實現數組去重? 2. HTTP狀態碼及其含義? 3. html5有哪些新特性、移除了那些元素? 4. display: none;與visibility: hidden;的區別? 5. 如何解決跨域問題? 6. XML和JSON的區別? ...
  • jquery DOM 分為元素操作、屬性操作、樣式操作。 一、元素操作 1、查找 ①工具:jQuery選擇器 2、創建和添加 ①代碼格式:變數 = $('要創建的元素'); 註意點: 1 要使用標準的XHTML格式。 2 不能使用$("<p>")或者$("<P/>")。 3 可以在標簽內添加文本當做 ...
  • 1JS簡介特點:跨平臺 弱類型 基於對象 函數式編程 跨平臺:可以再不同的系統上運行 弱類型:Java是強類型 給什麼數據就是什麼類型 基於對象:面向對象 函數式編程 腳本語言:js運行依賴於一個網頁,不能獨立運行 2JS輸出方式 alert();console.log();document.wri ...
  • 獲取元素DOM對象有很多種方法,以前一直在用getElementById和getElementsByTagName等,現在對這些方法和querySelector做一個總結. 常見的獲取元素的方法有3種,分別是通過元素ID、通過標簽名字和通過類名字來獲取。 DOM提供了一個名為getElementBy ...
  • 1. Outline(適用範圍:滑鼠懸浮hover加外邊框) 我們在佈局的時候,常常會因為添加邊框border影響寬高的佈局。 那麼,outline是完美的替代品,因為它可以在不影響文檔流的情況下呈現該對象。但是IE6 和IE7 不支持 outline 屬性。所以,它不能在這兩個瀏覽器中用於調試。 ...
  • 原文地址: "https://blog.thoughtram.io/angular/2015/09/03/forward references in angular 2.html" 作者: "Christoph Burgdorf" 譯者註:文章內容比較老,控制台信息等與新框架不完全一致,理解思路即可 ...
  • javascript es6之前的面向對象方法: 一般使用構造函數來實現 可以看到瀏覽器的控制台已經出來結果了; 只是一些簡單的實例; 下麵是通過ES6的class 類來創建 看看列印的結果 結果和上面用構造函數創建的是一樣的;當然裡面也可以寫方法 function; 可用原型對象來創建: Pers ...
  • 傳統的佈局解決方案 盒狀模型 diplay + position + float 缺陷:對於一些特殊佈局(垂直居中)和網格式佈局(幾行幾列)不易實現 09年W3C頒佈的 flex佈局 使用簡單、API完整豐富、響應式動態地實現各種頁面佈局(一些常見的佈局思想) 當然針對Gekco30+以下,最好的布 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...