以前在學習Socket編程時都只是簡單的調用微軟的API函數,很少考慮網路的異常處理。在做實際的項目中網路異常是必須要考慮到的。
網路斷開掉線異常處理: HeartBeat 網絡心跳包
一下是個人理解,網絡心跳包的處理方式有兩種“
方式一: 終端主動發起, 服務器記錄各個終端最後一個包的時間點,然後定時掃描全部客戶端,如果掃描時間點與上次收包時間點相隔時間大於超時時間,則
超時事件發生。服務器清除客戶端信息記錄。
方式二: 服務器主動發起, 服務器定時發送心跳包,通過記錄客戶端連續多少次未有迴應,則認爲超時事件發生。如果多次沒有收到迴應但在一定範圍內又收到迴應,
則清除記錄。如果連續未收到迴應達到一定量,則默認網絡異常發生。
typedef struct tagSocketPacket
{
CString tagStrDeviveID;
SOCKET tagSocket;
SYSTEMTIME tagRecTimer;
}SocketPacket,*pSocketPacket;
typedef vector<SocketPacket> vectorSocketPacket;
void HeartBeat(SOCKET socket)
{
SYSTEMTIME timer;
SocketPacket socketPacket;
vectorSocketPacket::iterator it;
for (it = myVectorPacket.begin(); it != myVectorPacket.end(); it++)
{
if (socket == (*it).tagSocket)
{
GetSystemTime(&timer);
socketPacket = (*it);
socketPacket.tagRecTimer = timer;
myVectorPacket.erase(it);
VectorPacket_insert(socketPacket);
break;
}
}
}
void VectorPacket_insert(SocketPacket socketPacket)
{
myVectorPacket.push_back(socketPacket);
}
BOOL IsTimeOuts(SYSTEMTIME Timer)
{
SYSTEMTIME sysTimer;
GetSystemTime(&sysTimer);
DWORD times1, times2;
times1 = Timer.wHour*3600+Timer.wMinute*60+Timer.wSecond;
times2 = sysTimer.wHour*3600+sysTimer.wMinute*60+sysTimer.wSecond;
if (times2 - times1 > TIMEOUTS)
{
return TRUE;
}
return FALSE;
}