1. 程式人生 > 其它 >19心跳包機制的實現

19心跳包機制的實現

一、為什麼引入心跳包

常規客戶端關閉,伺服器端能感知到;
一種特殊情況,連線斷開c/s都感知不到:
拔掉c/s程式的網線; "拔掉網線導致伺服器感知不到客戶端斷開",這個事實,大家一定要知道;那為了應對拔網線,導致不知道對方是否斷開了tcp連線這種事,這就是我們引入心跳包機制的原因;超時沒有傳送來心跳包,那麼就會將對端的socket連線close掉,回收資源;這就是心跳包的作用;
其他作用: 檢測網路延遲。
tcp本身keepalive機制;因為檢測時間不好控制,所以不適合。

二、實際程式碼

2.1 邏輯處理位置

ps:心跳包本身是作為一個數據包的格式傳給伺服器的,所以,具體的處理位置就是在業務處理程式碼上。

對於怎麼去接收處理一個數據包的邏輯問題,在前面就已經講過。這裡直接上程式碼。

2.2 這個近期的最新時間是怎麼被利用的

1.首先,是否踢人,和設定心跳包的時間是在配置檔案中的。

2.當一個連線進來的時候,那麼就把這個連線加入到時間佇列中去

std::multimap<time_t, LPSTRUC_MSG_HEADER>   m_timerQueuemap;          //時間佇列


3.建立一個服務處理到期不發心跳包使用者的踢出連線的執行緒

4.執行緒入口函式ServerTimerQueueMonitorThread
(1)第一步就是把時間佇列中最近的時間點取出進行判斷(有沒有到最近時間)
(2)要是比當前時間小,那麼,時間佇列中就有大於等於1個的超時(20S)連線,把這些超時連線放入另外一個佇列中進行判斷,比較的是,時間佇列中的時間和當前時間。



(3)當另外一個佇列不為空時,那麼就放入pSocketObj->procPingTimeOutChecking(tmpmsg,cur_time);進行進行檢查(可以說是二次檢查)。這個函式是在連線的子類中實現的。比較的是,當前時間和這個連線的ping包時間。

(4)要是這個判斷標準成立了,那麼就主動關閉套接字。

PS:這裡是三個時間,不一樣的三個變數儲存

2.3一些其他處理

比如說:
客戶端主動關閉的套接字,就要將該連線從時間佇列中取出出來。