我有同样的问题,并找到recv总是重演ConnNoError的原因。这是我发现的。当建立连接时,recv的调用一个名为dataAvailable在ConnectionTCPBase.cpp功能可按其返回
((select(m_socket + 1, &fds, 0, 0, timeout == -1 ? 0 : &tv) > 0) && FD_ISSET(m_socket, &fds) != 0)
谷歌搜索,I found this thread,故称FD_ISSET(m_socket,& FDS)将检测插座readble但不关闭... FD_ISSET(m_socket,& fds)的返回值始终为0,即使网络已关闭。在这种情况下,dataAvailable的返回值为false,因此下面的代码最终会在recv中返回ConnNoError。
if(!dataAvailable(timeout))
{
m_recvMutex.unlock();
return ConnNoError;
}
我不知道它是一个错误还是什么,似乎不是。
后来我尝试了另一种方式,直接写入套接字,如果套接字关闭,这将导致SIGPIPE,捕获该信号,然后使用清理断开连接。
我终于弄清楚了这个问题的一个优雅的解决方案,使用心跳。
在gloox线程
,调用心跳(),其中m_pClient是一个指针gloox的实例::客户
void CXmpp::heartBeat()
{
m_pClient->xmppPing(m_pClient->jid(), this);
if (++heart) > 3) {
m_pClient->disconnect();
}
}
xmppPing将自己注册到事件处理程序,当平安回来,它会调用的handleEvent ,并在为handleEvent
void CEventHandler::handleEvent(const Event& event)
{
std::string sEvent;
switch (event.eventType())
{
case Event::PingPing:
sEvent = "PingPing";
break;
case Event::PingPong:
sEvent = "PingPong";
//recieve from server, decrease the count of heart
--heart;
break;
case Event::PingError:
sEvent = "PingError";
break;
default:
break;
}
return;
}
连接到服务器,关闭网络,3秒后,我得到了一个断开!