首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++ / Gloox:当连接中断时如何检查?

C++ / Gloox:当连接中断时如何检查?
EN

Stack Overflow用户
提问于 2010-08-23 04:39:25
回答 2查看 2.2K关注 0票数 4

我正在尝试用c++/gloox编写自己的jabber机器人。一切都很顺利,但当互联网连接中断时-机器人认为它仍在连接,而当连接再次连接-机器人当然不会响应任何消息。

每次机器人成功连接后,gloox的recv()都会返回ConnNoError,即使接口已关闭且电缆已拔下。

尝试使用阻塞和非阻塞gloox的connection和recv(),都没有任何结果。定期检查不同线程中xmpp服务器的可用性似乎不是一个好主意,那么如何正确地检查bot现在是否连接?

如果不能只使用gloox -请告诉我一些好的方法,但让它在unix中可用。

EN

回答 2

Stack Overflow用户

发布于 2012-10-04 13:47:11

我也有同样的问题,并找到了recv总是返回ConnNoError的原因。这就是我发现的。连接建立后,recv调用ConnectionTCPBase.cpp中名为dataAvailable的函数,该函数返回

代码语言:javascript
复制
( ( 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 )会检测到插座是可读的,但不是关闭的……FD_ISSET( m_socket,&fds )的返回值始终为0,即使网络中断也是如此。在这种情况下,recv的返回值为false,因此下面的代码最终在dataAvailable中返回ConnNoError。

代码语言:javascript
复制
if( !dataAvailable( timeout ) )
{
  m_recvMutex.unlock();
  return ConnNoError;
}

我不知道这是一个bug还是什么,看起来不是。

后来我尝试了另一种方法,直接写入套接字,如果套接字关闭,则会导致SIGPIPE,捕获该信号,然后使用cleanup断开连接。

我最终找到了这个问题的一个很好的解决方案,使用了心跳。

在gloox线程中,调用heartBeat(),其中m_pClient是指向gloox::Client实例的指针

代码语言:javascript
复制
void    CXmpp::heartBeat()
{
    m_pClient->xmppPing(m_pClient->jid(), this);
    if (++heart) > 3) {
        m_pClient->disconnect();
    }
}

xmppPing会将自身注册到eventhandler,当ping返回时,它将调用handleEvent,并且在handleEvent中

代码语言:javascript
复制
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秒后,我就断线了!

票数 3
EN

Stack Overflow用户

发布于 2011-10-12 18:20:43

您必须定义onDisconnect(ConnectionError e)才能处理disconnect事件。文档地址为http://camaya.net/api/gloox-0.9.9.12/classgloox_1_1ConnectionListener.html#a2

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3543294

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档