Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/124.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;/Gloox:如何检查连接何时关闭?_C++_Linux_Unix_Xmpp - Fatal编程技术网

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

C++ C++;/Gloox:如何检查连接何时关闭?,c++,linux,unix,xmpp,C++,Linux,Unix,Xmpp,我正试图在c++/gloox上编写自己的jabber机器人。一切正常,但当互联网连接断开时——机器人认为它仍然连接,当连接再次接通时——当然,机器人不会响应任何消息 自从bot成功连接后,gloox'recv()每次都返回ConnNoError,即使接口已关闭且电缆已拔出 尝试使用阻塞和非阻塞gloox的连接和recv(),但都没有任何结果。定期检查不同线程中xmpp服务器的可用性似乎不是一个好主意,所以如何正确地检查现在是否连接了bot 如果无法仅使用gloox—请向我介绍一些好方法,但让它在

我正试图在c++/gloox上编写自己的jabber机器人。一切正常,但当互联网连接断开时——机器人认为它仍然连接,当连接再次接通时——当然,机器人不会响应任何消息

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

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


如果无法仅使用gloox—请向我介绍一些好方法,但让它在unix中可用。

您必须定义onDisconnect(ConnectionError)才能处理断开连接事件。文档的地址是

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

( ( select( m_socket + 1, &fds, 0, 0, timeout == -1 ? 0 : &tv ) > 0 ) && FD_ISSET( m_socket, &fds ) != 0 )
搜索谷歌时,它说FD_ISSET(m_socket,&fds)会检测到套接字是可读的,但不是关闭的。。。FD_ISSET(m_socket,&fds)的返回值始终为0,即使网络已关闭。在这种情况下,dataAvailable的返回值为false,因此下面的代码最终在recv中返回ConnNoError

if( !dataAvailable( timeout ) )
{
  m_recvMutex.unlock();
  return ConnNoError;
}
我不知道这是一个错误还是什么,似乎不是

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

我终于找到了一个优雅的解决方案,使用heartbeat

在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秒钟后,我断开了连接