欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

秒懂即时通讯里的网络心跳包:用途、工作原理和实现方法

最编程 2024-08-09 07:16:20
...

bool CIUSocket::Send()

{

intnSentBytes = 0;

intnRet = 0;

while(true)

{

nRet = ::send(m_hSocket, m_strSendBuf.c_str(), m_strSendBuf.length(), 0);

if(nRet == SOCKET_ERROR)

{

if(::WSAGetLastError() == WSAEWOULDBLOCK)

break;

else

{

LOG_ERROR("Send data error, disconnect server:%s, port:%d.", m_strServer.c_str(), m_nPort);

Close();

returnfalse;

}

}

elseif(nRet < 1)

{

//一旦出现错误就立刻关闭Socket

LOG_ERROR("Send data error, disconnect server:%s, port:%d.", m_strServer.c_str(), m_nPort);

Close();

returnfalse;

}

m_strSendBuf.erase(0, nRet);

if(m_strSendBuf.empty())

break;


::Sleep(1);

}

{

//记录一下最近一次发包时间

std::lock_guard<std::mutex> guard(m_mutexLastDataTime);

m_nLastDataTime = (long)time(NULL);

}

returntrue;

}

bool CIUSocket::Recv()

{

intnRet = 0;

charbuff[10 * 1024];

while(true)

{

nRet = ::recv(m_hSocket, buff, 10 * 1024, 0);

if(nRet == SOCKET_ERROR) //一旦出现错误就立刻关闭Socket

{

if(::WSAGetLastError() == WSAEWOULDBLOCK)

break;

else

{

LOG_ERROR("Recv data error, errorNO=%d.", ::WSAGetLastError());

//Close();

returnfalse;

}

}

elseif(nRet < 1)

{

LOG_ERROR("Recv data error, errorNO=%d.", ::WSAGetLastError());

//Close();

returnfalse;

}

m_strRecvBuf.append(buff, nRet);

::Sleep(1);

}

{

std::lock_guard<std::mutex> guard(m_mutexLastDataTime);

//记录一下最近一次收包时间

m_nLastDataTime = (long)time(NULL);

}

returntrue;

}

voidCIUSocket::RecvThreadProc()

{

LOG_INFO("Recv data thread start...");

intnRet;

//上网方式

DWORDdwFlags;

BOOLbAlive;

while(!m_bStop)

{

//检测到数据则收数据

nRet = CheckReceivedData();

//出错

if(nRet == -1)

{

m_pRecvMsgThread->NotifyNetError();

}

//无数据

elseif(nRet == 0)

{

longnLastDataTime = 0;

{

std::lock_guard<std::mutex> guard(m_mutexLastDataTime);

nLastDataTime = m_nLastDataTime;

}

if(m_nHeartbeatInterval > 0)

{

//当前系统时间与上一次收发数据包的时间间隔超过了m_nHeartbeatInterval

//则发一次心跳包

if(time(NULL) - nLastDataTime >= m_nHeartbeatInterval)

SendHeartbeatPackage();

}

}

//有数据

elseif(nRet == 1)

{

if(!Recv())

{

m_pRecvMsgThread->NotifyNetError();

continue;

}

DecodePackages();

}// end if

}// end while-loop

LOG_INFO("Recv data thread finish...");

}