簡體   English   中英

boost :: asio tcp服務器斷開連接問題

[英]boost::asio tcp server disconnect issue

我目前正在使用boost :: asio TCP套接字編寫一個TCP服務器。 我使用了提供的示例,通過將套接字對象包裝在我自己的會話對象中,使服務器變為全狀態。

除斷開連接外,一切正常。 在我的設置中,我總是為每個打開的套接字調用async_read_some
正常行為是當我連接客戶端並斷開連接時。 調用數據讀取處理程序並設置了錯誤,因此我知道套接字已斷開連接。
不良行為是當我以一個順序連接2個客戶端並以相同順序關閉它們時。 當我關閉第一個客戶端時,沒有任何處理程序被調用,但是當我關閉第二個客戶端時,我也獲得了第一個客戶端的調用,兩者均通知斷開連接。
除此問題外,其他所有功能似乎都運行良好。 在多個客戶端上發送和接收數據工作正常。

有人遇到過這個問題嗎? 這可能是什么原因?

bool TCPNetworkListener::StartListener()
{
    //check if already started
    if (m_SocketAcceptor.is_open())
    {
        return false;
    }

    //create the socket acceptor
    m_SocketAcceptor.open(m_TCPEndpoint.protocol());
    m_SocketAcceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
    m_SocketAcceptor.bind(m_TCPEndpoint);
    m_SocketAcceptor.listen();

    //accept async connections
    m_lastConnectedClientId++;
    TCPNetworkSession::SharedPtr new_session(new TCPNetworkSession(m_IOService, this, m_lastConnectedClientId));
    m_SocketAcceptor.async_accept(new_session->GetSocket(),
                                    boost::bind(&TCPNetworkListener::HandleNewConnection, this, new_session,
                                    boost::asio::placeholders::error));

    //all fine
    m_listenerState = NetworkListener::NLState_Running;
    return true;
}

void TCPNetworkListener::HandleNewConnection( TCPNetworkSession::SharedPtr session, const boost::system::error_code& error )
{
    if (error)
    {
        return;
    }

    session->StartNewSession();

    //accept new async connections
    m_lastConnectedClientId++;
    TCPNetworkSession::SharedPtr new_session(new TCPNetworkSession(m_IOService, this, m_lastConnectedClientId));
    m_SocketAcceptor.async_accept(new_session->GetSocket(),
        boost::bind(&TCPNetworkListener::HandleNewConnection, this, new_session,
        boost::asio::placeholders::error));
}

該會話如下所示:

TCPNetworkSession::TCPNetworkSession( boost::asio::io_service& io_service , TCPNetworkListener* handler, long clientId) :
    m_socket(io_service),
    m_IOService(io_service),
    m_networkHandler(handler),
    m_clientId(clientId),
    m_sendingData(false)
{
}

tcp::socket& TCPNetworkSession::GetSocket()
{
    return m_socket;
}

void TCPNetworkSession::StartNewSession()
{
    //notify of new connection established
    if (m_networkHandler)
    {
        m_networkHandler->ClientConnected(shared_from_this());
    }

    m_socket.set_option(boost::asio::socket_base::keep_alive(true));

    //try to read the first message data
    m_socket.async_read_some(
        boost::asio::buffer(m_readBuffer, SOCKETBUFFERLENGTH),
        boost::bind(&TCPNetworkSession::HandleReadData, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
}

void TCPNetworkSession::HandleReadData( const boost::system::error_code& error, std::size_t bytes_transferred )
{
    if (error)
    {
        //we have got disconnected
        if (m_networkHandler)
        {
            m_networkHandler->ClientDisconnected(shared_from_this());
        }

        return;
    }

    //we received new data
    if (m_networkHandler)
    {
        m_readBuffer[bytes_transferred] = 0;
        std::string strData(reinterpret_cast<const char*>(m_readBuffer), bytes_transferred);
        m_networkHandler->ClientDataReceived(shared_from_this(), strData);
    }

    //try to read the next message data
    m_socket.async_read_some(
        boost::asio::buffer(m_readBuffer, SOCKETBUFFERLENGTH),
        boost::bind(&TCPNetworkSession::HandleReadData, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
}

問題出在膩子上。 我使用它來使用telnet測試服務器並根據需要復制會話。 膩子中似乎有一個錯誤,當您關閉會話窗口時,該錯誤會導致套接字無法關閉。 僅當最后一次膩子會話關閉時,套接字才會關閉。

謝謝大家提供的幫助

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM