以前在学习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;
- }