C++ Socket心跳包機制(Windows環境下)

https://www.csdn.net/gather_2d/NtzaMg1sMTktYmxvZwO0O0OO0O0O.html 參考文件

心跳包機制

跳包之所以叫心跳包是因爲:它像心跳一樣每隔固定時間發一次,以此來告訴服務器,這個客戶端還活着。事實上這是爲了保持長連接,至於這個包的內容,是沒有什麼特別規定的,不過一般都是很小的包,或者只包含包頭的一個空包。
在TCP的機制裏面,本身是存在有心跳包的機制的,也就是TCP的選項:SO_KEEPALIVE。系統默認是設置的2小時的心跳頻率。但是它檢查不到機器斷電、網線拔出、防火牆這些斷線。而且邏輯層處理斷線可能也不是那麼好處理。一般,如果只是用於保活還是可以的。
心跳包一般來說都是在邏輯層發送空的echo包來實現的。下一個定時器,在一定時間間隔下發送一個空包給客戶端,然後客戶端反饋一個同樣的空包回來,服務器如果在一定時間內收不到客戶端發送過來的反饋包,那就只有認定說掉線了。
其實,要判定掉線,只需要send或者recv一下,如果結果爲零,則爲掉線。但是,在長連接下,有可能很長一段時間都沒有數據往來。理論上說,這個連接是一直保持連接的,但是實際情況中,如果中間節點出現什麼故障是難以知道的。更要命的是,有的節點(防火牆)會自動把一定時間之內沒有數據交互的連接給斷掉。在這個時候,就需要我們的心跳包了,用於維持長連接,保活。
在獲知了斷線之後,服務器邏輯可能需要做一些事情,比如斷線後的數據清理呀,重新連接呀……當然,這個自然是要由邏輯層根據需求去做了。
總的來說,心跳包主要也就是用於長連接的保活和斷線處理。一般的應用下,判定時間在30-40秒比較不錯。如果實在要求高,那就在6-9秒。

心跳檢測步驟:

1 客戶端每隔一個時間間隔發生一個探測包給服務器
2 客戶端發包時啓動一個超時定時器
3 服務器端接收到檢測包,應該回應一個包
4 如果客戶機收到服務器的應答包,則說明服務器正常,刪除超時定時器
5 如果客戶端的超時定時器超時,依然沒有收到應答包,則說明服務器掛了

具體實現:
這裏用到了 C++自帶的 thread庫
以下爲簡單實現的主要部分代碼(開個線程不斷的發送探測包,設定間隔多長時間一個)

#include <thread>
using std::thread;

//單開一個線程去不斷地發探測包
thread heartTh = new thread(SocketThread::send_heart(線程執行調用的方法),(void*)this(該方法的參數));
heartTh ->detach();

//在h文件中爲靜態方法
void SocketThread::send_heart(void* arg)   
{
    //該類
	SocketThread* client = (SocketThread*)arg;
	while (true)
	{
		Sleep(3000);   //定時3秒  此處的單位爲毫秒
		string tempdata = "";   //空包
		int result = client->SendData(tempdata);
		if (result<0) //result>0是發送成功的返回碼  小於零就是發送失敗
		{
			MessageBox(NULL, "Socket服務端已關閉!!!", "提示", MB_OK|MB_SYSTEMMODAL);
			break;
		}
		Sleep(5000);    //定時3秒  此處的單位爲毫秒
	}
}


int SocketThread::SendData(string data)
{
	int result = send(s_server, data.c_str(), data.length(), 0);
	return result;
}

注:此篇是基於Socket實現鏈接的基礎上進行心跳包的發送

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章