為什么心跳包(HeartBeat)是必須的?


幾乎所有的網游服務端都有心跳包(HeartBeat或Ping)的設計,在最近開發手游服務端時,也用到了心跳包。思考思考,心跳包是必須的嗎?為什么需要心跳包?TCP沒有提供斷線檢測的方法嗎?TCP提供的KeepAlive機制可以替代HeartBeat嗎?

由於連接丟失時,TCP不會立即通知應用程序。比如說,客戶端程序斷線了,服務端的TCP連接不會檢測到斷線,而是一直處於連接狀態。這就帶來了很大的麻煩,明明客戶端已經斷了,服務端還維護着客戶端的連接,照常執行着該玩家的游戲邏輯……

心跳包就是用來及時檢測是否斷線的一種機制,通過每間隔一定時間發送心跳數據,來檢測對方是否連接。是屬於應用程序協議的一部分。

問題1: TCP為什么不自己提供斷線檢測?

首先,斷線檢測需要輪詢發送檢測報文,會消耗一定的網絡帶寬和暫用一定的網絡資源。如果把它做成TCP的底層默認功能,那些不需要斷線檢測的應用程序將會浪費不必要的帶寬資源。

另外,TCP不提供連接丟失及時通知的最重要原因與其主要設計目的目標之一有關:出現網絡故障時維護通信的能力。TCP是美國國防部贊助研究的,一種即使發生戰爭或自然災害這種嚴重網絡損壞情況下,也能維護可靠網絡通信的網絡協議。通常,網絡故障只是暫時的,有時路由器會在TCP臨時連接丟失后默默的重新連上。所以,TCP本身並不提供那么及時的斷線檢測。

問題2: TCP的KeepAlive機制可以用來及時檢測連接狀態嗎?

TCP有個KeepAlive開關,打開后可以用來檢測死連接。通常默認是2小時,可以自己設置。但是注意,這是TCP的全局設置。假如為了能更及時的檢測出斷開的連接,把tcp_keepalive_timetcp_keepalive_intvl的時間改小(參考:Link),該機器上所有應用程序的KeepAlive檢測間隔都會變小,顯然是不能接受的。因為不同應用程序的需求是不一樣的。

(在某些平台的Socket實現已經支持為每條連接單獨設置KeepAlive參數)

KeepAlive本質上來說,是用來檢測長時間不活躍的連接的。所以,不適合用來及時檢測連接的狀態。

問題3:心跳包(HeartBeat)為什么是好的方式及時檢測連接狀態?

  1. 具有更大的靈活性,可以自己控制檢測的間隔,檢測的方式等等。
  2. 心跳包同時適用於TCP和UDP,在切換TCP和UDP時,上層的心跳包功能都適用。(其實這種情況很少遇到)
  3. 有些情況下,心跳包可以附帶一些其他信息,定時在服務端和客戶端之間同步。(比如幀數同步)

結論

需要及時檢測TCP連接狀態,心跳包(HeartBeat)還是必須的。

轉自我的獨立博客:http://blog.coderzh.com/2015/03/05/WhyHeartBeatNeeded/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM