- UDP:用戶數據報協議:主要用在實時性要求比較高的以及對質量相對較弱的地方.但是面對現在高質量的線路不會容易丟包,除非是一些擁塞條件下,如流媒體
- TCP:傳輸控制協議:是面連接的那么運行環境必然要求其可靠性不可丟包,有良好的擁塞控制機制如 http ftp telnet等
TCP | UDP | |
---|---|---|
發送 | 安全送達 | 只管發送 |
接收與建立連接 | 是(三次握手) | 否(有數據包,無需連接) |
數據大小 | 無限制 | 每個數據報64k |
可靠性 | 可靠 | 不可靠 |
速度 | 慢(三次握手才能完成連接) | 快(無需連接) |
應用 | 流媒體 |
什么是三次握手?
握手次數 | 具體情況 |
---|---|
1 | 建立連接時,客戶端發送同步序列編號到服務器,并進入發送狀態,等待服務器確認 |
2 | 服務器收到同步序列編號,確認并同時自己也發送一個同步序列編號+確認標識,此時服務器進入接收狀態 |
3 | 客戶端收到服務器發送的包,并向服務器發送確認標識,隨后連接成功 |
注意:是在連接成功后進行數據傳輸 |
什么是四次揮手?
揮手次數 | 具體情況 |
---|---|
1 | 客戶端向服務器發送一個帶有結束標記的報文 |
2 | 服務器收到報文后,向客戶端發送一個確認序號,同時通知自己相應的應用程序:對方要求關閉連接 |
3 | 服務器向客戶端發送一個帶有結束標記的報文 |
4 | 客戶端收到報文后,向服務器發送一個確認序號,連接關閉 |
心跳機制
心跳機制是定時發送一個自定義的結構體(心跳包),讓對方知道自己還活著,以確保連接的有效性的機制。(看下圖)
網絡中的接收和發送數據都是使用操作系統中的SOCKET進行實現。但是如果此套接字已經斷開,那發送數據和接收數據的時候就一定會有問題??墒侨绾闻袛噙@個套接字是否還可以使用呢?這個就需要在系統中創建心跳機制。其實TCP中已經為我們實現了一個叫做心跳的機制。如果你設置了心跳,那TCP就會在一定的時間(比如你設置的是3秒鐘)內發送你設置的次數的心跳(比如說2次),并且此信息不會影響你自己定義的協議。所謂“心跳”就是定時發送一個自定義的結構體(心跳包或心跳幀),讓對方知道自己“在線”。 以確保鏈接的有效性。
所謂的心跳包就是客戶端定時發送簡單的信息給服務器端告訴它我還在而已。代碼就是每隔幾分鐘發送一個固定信息給服務端,服務端收到后回復一個固定信息如果服務端幾分鐘內沒有收到客戶端信息則視客戶端斷開。比如有些通信軟件長時間不使用,要想知道它的狀態是在線還是離線就需要心跳包,定時發包收包。發包方:可以是客戶也可以是服務端,看哪邊實現方便合理。一般是客戶端。服務器也可以定時輪詢發心跳下去。心跳包之所以叫心跳包是因為:它像心跳一樣每隔固定時間發一次,以此來告訴服務器,這個客戶端還活著。事實上這是為了保持長連接,至于這個包的內容,是沒有什么特別規定的,不過一般都是很小的包,或者只包含包頭的一個空包。
在TCP的機制里面,本身是存在有心跳包的機制的,也就是TCP的選項。系統默認是設置的是2小時的心跳頻率。但是它檢查不到機器斷電、網線拔出、防火墻這些斷線。而且邏輯層處理斷線可能也不是那么好處理。一般,如果只是用于?;钸€是可以的。心跳包一般來說都是在邏輯層發送空的包來實現的。下一個定時器,在一定時間間隔下發送一個空包給客戶端,然后客戶端反饋一個同樣的空包回來,服務器如果在一定時間內收不到客戶端發送過來的反饋包,那就只有認定說掉線了。只需要send或者recv一下,如果結果為零,則為掉線。
但是,在長連接下,有可能很長一段時間都沒有數據往來。理論上說,這個連接是一直保持連接的,但是實際情況中,如果中間節點出現什么故障是難以知道的。更要命的是,有的節點(防火墻)會自動把一定時間之內沒有數據交互的連接給斷掉。在這個時候,就需要我們的心跳包了,用于維持長連接,?;睢T讷@知了斷線之后,服務器邏輯可能需要做一些事情,比如斷線后的數據清理呀,重新連接呀當然,這個自然是要由邏輯層根據需求去做了??偟膩碚f,心跳包主要也就是用于長連接的?;詈蛿嗑€處理。一般的應用下,判定時間在30-40秒比較不錯。如果實在要求高,那就在6-9秒。
心跳檢測步驟:
1.客戶端每隔一個時間間隔發生一個探測包給服務器
2.客戶端發包時啟動一個超時定時器
3.服務器端接收到檢測包,應該回應一個包
4.如果客戶機收到服務器的應答包,則說明服務器正常,刪除超時定時器
5.如果客戶端的超時定時器超時,依然沒有收到應答包,則說明服務器掛了
心跳包的發送,通常有兩種技術
方法1:應用層自己實現的心跳包
由應用程序自己發送心跳包來檢測連接是否正常,大致的方法是:服務器在一個 Timer事件中定時 向客戶端發送一個短小精悍的數據包,然后啟動一個低級別的線程,在該線程中不斷檢測客戶端的回應, 如果在一定時間內沒有收到客戶端的回應,即認為客戶端已經掉線;同樣,如果客戶端在一定時間內沒 有收到服務器的心跳包,則認為連接不可用。方法2:TCP的KeepAlive?;顧C制
因為要考慮到一個服務器通常會連接多個客戶端,因此由用戶在應用層自己實現心跳包,代碼較多 且稍顯復雜,而利用TCP/IP協議層為內置的KeepAlive功能來實現心跳功能則簡單得多。 不論是服務端還是客戶端,一方開啟KeepAlive功能后,就會自動在規定時間內向對方發送心跳包, 而另一方在收到心跳包后就會自動回復,以告訴對方我仍然在線。 因為開啟KeepAlive功能需要消耗額外的寬帶和流量,所以TCP協議層默認并不開啟KeepAlive功 能,盡管這微不足道,但在按流量計費的環境下增加了費用,另一方面,KeepAlive設置不合理時可能會 因為短暫的網絡波動而斷開健康的TCP連接。并且,默認的KeepAlive超時需要7,200,000 MilliSeconds, 即2小時,探測次數為5次。對于很多服務端應用程序來說,2小時的空閑時間太長。因此,我們需要手工開啟KeepAlive功能并設置合理的KeepAlive參數。