天天看點

TCP/UDP差別&&心跳包機制

  • UDP:使用者資料報協定:主要用在實時性要求比較高的以及對品質相對較弱的地方.但是面對現在高品質的線路不會容易丢包,除非是一些擁塞條件下,如流媒體
  • TCP:傳輸控制協定:是面連接配接的那麼運作環境必然要求其可靠性不可丢包,有良好的擁塞控制機制如 http ftp telnet等
TCP UDP
發送 安全送達 隻管發送
接收與建立連接配接 是(三次握手) 否(有資料包,無需連接配接)
資料大小 無限制 每個資料報64k
可靠性 可靠 不可靠
速度 慢(三次握手才能完成連接配接) 快(無需連接配接)
應用 流媒體 qq

什麼是三次握手?

握手次數 具體情況
1 建立連接配接時,用戶端發送同步序列編号到伺服器,并進入發送狀态,等待伺服器确認
2 伺服器收到同步序列編号,确認并同時自己也發送一個同步序列編号+确認辨別,此時伺服器進入接收狀态
3 用戶端收到伺服器發送的包,并向伺服器發送确認辨別,随後連接配接成功
注意:是在連接配接成功後進行資料傳輸

什麼是四次揮手?

揮手次數
用戶端向伺服器發送一個帶有結束标記的封包
伺服器收到封包後,向用戶端發送一個确認序号,同時通知自己相應的應用程式:對方要求關閉連接配接
伺服器向用戶端發送一個帶有結束标記的封包
4 用戶端收到封包後,向伺服器發送一個确認序号,連接配接關閉

心跳機制

心跳機制是定時發送一個自定義的結構體(心跳包),讓對方知道自己還活着,以確定連接配接的有效性的機制。(看下圖)

TCP/UDP差別&&心跳包機制
TCP/UDP差別&&心跳包機制

網絡中的接收和發送資料都是使用作業系統中的SOCKET進行實作。但是如果此套接字已經斷開,那發送資料和接收資料的時候就一定會有問題。可是如何判斷這個套接字是否還可以使用呢?這個就需要在系統中建立心跳機制。其實TCP中已經為我們實作了一個叫做心跳的機制。如果你設定了心跳,那TCP就會在一定的時間(比如你設定的是3秒鐘)内發送你設定的次數的心跳(比如說2次),并且此資訊不會影響你自己定義的協定。所謂“心跳”就是定時發送一個自定義的結構體(心跳包或心跳幀),讓對方知道自己“線上”。 以確定連結的有效性。

所謂的心跳包就是用戶端定時發送簡單的資訊給伺服器端告訴它我還在而已。代碼就是每隔幾分鐘發送一個固定資訊給服務端,服務端收到後回複一個固定資訊如果服務端幾分鐘内沒有收到用戶端資訊則視用戶端斷開。比如有些通信軟體長時間不使用,要想知道它的狀态是線上還是離線就需要心跳包,定時發包收包。發包方:可以是客戶也可以是服務端,看哪邊實作友善合理。一般是用戶端。伺服器也可以定時輪詢發心跳下去。心跳包之是以叫心跳包是因為:它像心跳一樣每隔固定時間發一次,以此來告訴伺服器,這個用戶端還活着。事實上這是為了保持長連接配接,至于這個包的内容,是沒有什麼特别規定的,不過一般都是很小的包,或者隻包含標頭的一個空包。

在TCP的機制裡面,本身是存在有心跳包的機制的,也就是TCP的選項。系統預設是設定的是2小時的心跳頻率。但是它檢查不到機器斷電、網線拔出、防火牆這些斷線。而且邏輯層處理斷線可能也不是那麼好處理。一般,如果隻是用于保活還是可以的。心跳包一般來說都是在邏輯層發送空的包來實作的。下一個定時器,在一定時間間隔下發送一個空包給用戶端,然後用戶端回報一個同樣的空包回來,伺服器如果在一定時間内收不到用戶端發送過來的回報包,那就隻有認定說掉線了。隻需要send或者recv一下,如果結果為零,則為掉線。

但是,在長連接配接下,有可能很長一段時間都沒有資料往來。理論上說,這個連接配接是一直保持連接配接的,但是實際情況中,如果中間節點出現什麼故障是難以知道的。更要命的是,有的節點(防火牆)會自動把一定時間之内沒有資料互動的連接配接給斷掉。在這個時候,就需要我們的心跳包了,用于維持長連接配接,保活。在獲知了斷線之後,伺服器邏輯可能需要做一些事情,比如斷線後的資料清理呀,重新連接配接呀當然,這個自然是要由邏輯層根據需求去做了。總的來說,心跳包主要也就是用于長連接配接的保活和斷線處理。一般的應用下,判定時間在30-40秒比較不錯。如果實在要求高,那就在6-9秒。

心跳檢測步驟:

1.用戶端每隔一個時間間隔發生一個探測包給伺服器

2.用戶端發包時啟動一個逾時定時器

3.伺服器端接收到檢測包,應該回應一個包

4.如果客戶機收到伺服器的應答包,則說明伺服器正常,删除逾時定時器

5.如果用戶端的逾時定時器逾時,依然沒有收到應答包,則說明伺服器挂了

心跳包的發送,通常有兩種技術

  • 方法1:應用層自己實作的心跳包

    由應用程式自己發送心跳包來檢測連接配接是否正常,大緻的方法是:伺服器在一個 Timer事件中定時 向用戶端發送一個短小精悍的資料包,然後啟動一個低級别的線程,在該線程中不斷檢測用戶端的回應, 如果在一定時間内沒有收到用戶端的回應,即認為用戶端已經掉線;同樣,如果用戶端在一定時間内沒 有收到伺服器的心跳包,則認為連接配接不可用。

  • 方法2:TCP的KeepAlive保活機制

    因為要考慮到一個伺服器通常會連接配接多個用戶端,是以由使用者在應用層自己實作心跳包,代碼較多 且稍顯複雜,而利用TCP/IP協定層為内置的KeepAlive功能來實作心跳功能則簡單得多。 不論是服務端還是用戶端,一方開啟KeepAlive功能後,就會自動在規定時間内向對方發送心跳包, 而另一方在收到心跳包後就會自動回複,以告訴對方我仍然線上。 因為開啟KeepAlive功能需要消耗額外的寬帶和流量,是以TCP協定層預設并不開啟KeepAlive功 能,盡管這微不足道,但在按流量計費的環境下增加了費用,另一方面,KeepAlive設定不合理時可能會 因為短暫的網絡波動而斷開健康的TCP連接配接。并且,預設的KeepAlive逾時需要7,200,000 MilliSeconds, 即2小時,探測次數為5次。對于很多服務端應用程式來說,2小時的空閑時間太長。是以,我們需要手工開啟KeepAlive功能并設定合理的KeepAlive參數。

繼續閱讀