远程关闭连接一次后,不会发送提升asio ssl握手

时间:2014-09-26 13:19:20

标签: c++ sockets ssl boost boost-asio

在上次成功握手之后,我无法进行ssl握手。一旦连接并且握手完成,我的客户端可以长时间成功发送和接收。偶尔我会断开与服务器的连接,并显示错误“远程主机强行关闭现有连接。”。当发生这种情况时,我取消并关闭客户端上的套接字。然后我可以再次连接,但是当我启动async_handshake时,没有任何内容传输到服务器(wireshark显示没有活动)。然后我最终再次与服务器断开连接(可能是由于不活动),基本上是相同的错误“现有连接被远程主机强行关闭。”。我知道客户端在第一次断开连接之前正在发送和接收数据 - 所以不活动不是原因。一旦处于此状态,客户端每次尝试时都可以连接,但async_handshake从不传输任何内容,因此循环重复。

有什么想法吗?

以下是大部分代码:

连接:


    boost::asio::async_connect(
        m_socket.lowest_layer(), 
        endpoint_iterator,
        boost::bind(&CClientSock::handle_connect, 
        shared_from_this(),
        boost::asio::placeholders::error));

和其他


    void CClientSock::handle_connect(const boost::system::error_code& error)
    {
        if ( !error )
        {
            m_socket.async_handshake(
                boost::asio::ssl::stream_base::client,
                boost::bind(&CClientSock::handle_handshake, 
                shared_from_this(),
                boost::asio::placeholders::error)
                );
        }
        else
        {
            CloseSocket();
            m_eState = eDisconnected;
        }
    }

    void CClientSock::handle_handshake(
        const boost::system::error_code& error
        )
    {
        if (!error)
        {
            BeginRead();

            SendQuery();
        }
        else
        {
            CloseSocket();
            m_eState = eDisconnected;
        }
    }

    void CClientSock::BeginRead()
    {
        // Start an async read and always keep one going
        size_t bytes_transferred = BUFFER_SIZE;

        m_socket.async_read_some(
            boost::asio::buffer(rcvbuf, bytes_transferred),
            boost::bind(&CClientSock::handle_read, 
            shared_from_this(),
            boost::asio::placeholders::error,
            boost::asio::placeholders::bytes_transferred));
    }

    void CClientSock::SendQuery()
    {
        m_eState = eSending;

        m_bTMO = FALSE;

        size_t request_length = 0;


    #ifdef _USE_MODBUSTCP
            sndbuf [0] = 0x00;
            sndbuf [1] = m_bTxn;    m_bTxn++;
            sndbuf [2] = 0x00;
            sndbuf [3] = 0x00;
            sndbuf [4] = 0x00;
            sndbuf [5] = 0x06;
            sndbuf [6] = 0x01;
            sndbuf [7] = 0x03;
            sndbuf [8] = 0x1B;
            sndbuf [9] = 0x59;
            sndbuf [10] = 0x00;
            sndbuf [11] = 0x01;
            request_length = 12;
    #else
            sndbuf [0] = 0x01;
            sndbuf [1] = 0x03;
            sndbuf [2] = 0x1B;
            sndbuf [3] = 0x59;
            sndbuf [4] = 0x00;
            sndbuf [5] = 0x01;
            sndbuf [6] = 0x52;
            sndbuf [7] = 0xFD;
            request_length = 8;
    #endif

        boost::asio::async_write(m_socket,
            boost::asio::buffer(sndbuf, request_length),
            boost::bind(&CClientSock::handle_write, 
            shared_from_this(),
            boost::asio::placeholders::error,
            boost::asio::placeholders::bytes_transferred));
    }

    void CClientSock::handle_write(
        const boost::system::error_code& error,
        size_t bytes_transferred
        )
    {
        if ( !error )
        {
            // Already have an async_read started, so do nothing here.
            m_eState = eReceiving;
        }
        else
        {
            CloseSocket();
            m_eState = eDisconnected;
        }
    }


    void CClientSock::handle_read(
        const boost::system::error_code& error,
        size_t bytes_transferred
        )
    {
        if ( !error )
        {
            // start another async read
            BeginRead();

            // An external call starts another write when we're idle
            m_eState = eIdle;
        }
        else
        {
            CloseSocket();
            m_eState = eDisconnected;
        }
    }

    void CClientSock::CloseSocket()
    {
        bool bexcept = false;
        try
        {
    #ifdef _SSL_TEST
            if ( m_socket.lowest_layer().is_open() )
            {
                m_socket.lowest_layer().cancel();
                m_socket.lowest_layer().close();
            }
    #else
            if ( m_socket.is_open() )
            {
                m_socket.cancel();
                m_socket.close();
            }
    #endif
        }
        catch (std::exception& e)
        {
            bexcept = true;
        }
    }

0 个答案:

没有答案