C ++ / Gloox:如何检查连接何时关闭?

时间:2010-08-22 20:39:25

标签: c++ linux unix xmpp

我正在尝试在c ++ / gloox上编写自己的jabber bot。一切都很好,但是当互联网连接停止时 - 僵尸程序认为它仍然连接,当连接再次启动时 - 当然机器人不响应任何消息。

每次自bot成功连接后,gloox'recv()都会返回ConnNoError,即使接口已关闭且电缆已拔下插头。

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

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

2 个答案:

答案 0 :(得分:3)

我有同样的问题,并找到了为什么recv总是回溯ConnNoError。这是我发现的。建立连接后,recv调用一个名为dataAvailable的函数在ConnectionTCPBase.cpp中返回

( ( select( m_socket + 1, &fds, 0, 0, timeout == -1 ? 0 : &tv ) > 0 ) && FD_ISSET( m_socket, &fds ) != 0 )

搜索google,I found this thread,它说FD_ISSET(m_socket,& fds)会检测到套接字是可读的但是没有关闭... FD_ISSET(m_socket,& fds)的返回值始终为0,甚至网络都瘫痪了。在这种情况下,dataAvailable的返回值为false,因此下面的代码最终返回recv中的ConnNoError。

if( !dataAvailable( timeout ) )
{
  m_recvMutex.unlock();
  return ConnNoError;
}

我不知道这是一个bug还是什么,似乎没有。

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

我终于使用心跳来找出这个问题的优雅解决方案。

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

实例的指针
void    CXmpp::heartBeat()
{
    m_pClient->xmppPing(m_pClient->jid(), this);
    if (++heart) > 3) {
        m_pClient->disconnect();
    }
}

xmppPing会将自己注册到eventhandler,当ping返回时,它将调用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秒后,我断开连接!

答案 1 :(得分:0)

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