19心跳包機制的實現
阿新 • • 發佈:2022-03-21
一、為什麼引入心跳包
常規客戶端關閉,伺服器端能感知到;
有一種特殊情況,連線斷開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一些其他處理
比如說:
客戶端主動關閉的套接字,就要將該連線從時間佇列中取出出來。