Boost.Asio socket :: close不抛出boost :: asio :: error :: operation_aborted错误

时间:2015-10-12 18:35:53

标签: c++ sockets boost

Boost的官方网站socket :: close()函数,请参阅description

&#34;此函数导致所有未完成的异步连接,发送和接收操作立即完成,取消操作的处理程序将传递boost :: asio :: error :: operation_aborted错误。&#34; < / p>

但奇怪的是,当我调用chat_session :: close()时,socket :: close()传递ERROR_CONNECTION_ABORTED(1236)错误而不是boost :: asio :: error :: operation_aborted(995)。

为什么会这样? 这是我的chat_session课程。

class chat_session
    : public boost::enable_shared_from_this<chat_session>
{
public:
    chat_session(boost::asio::io_service& io, chat_server* room)
        : m_sock(io), m_room(room)
    {
    }

    ~chat_session()
    {
    }

    void start()
    {
        m_room.join(shared_from_this());

        m_sock.async_read_some(
            boost::asio::buffer(m_recv_data),
            boost::bind(&chat_session::handle_read, shared_from_this(),
            boost::asio::placeholders::error));
    }

    void close()
    {
        // closing socket. chat_session::handle_read will receive
        // boost::asio::error::operation_aborted error.
        m_sock.close(); 
    }

    boost::asio::ip::tcp::socket& socket()
    {
        return m_sock;
    }

    private:
    void handle_read(const boost::system::error_code& error)
    {
        if (!error)
        {
            printf("RECV -> %s.\n", m_recv_data);

            m_sock.async_read_some(
                boost::asio::buffer(m_recv_data),
                boost::bind(&chat_session::handle_read, shared_from_this(),
                boost::asio::placeholders::error));
        }
        else
        {
            // when i call chat_session::close(),
            // ERROR_CONNECTION_ABORTED (1236) error occurred
            // instead of boost::asio::error::operation_aborted error over here
            ...
            m_room.leave(shared_from_this());
        }
    }

    boost::asio::ip::tcp::socket m_sock;
    chat_room& m_room;
    char m_recv_data[50];
};

1 个答案:

答案 0 :(得分:3)

在关闭套接字之前先尝试在套接字上调用shutdown,因为boost basic_stream_socket :: close文档在备注here中指定:

  

说明

     

关于正常关闭连接套接字的可移植行为,请在关闭套接字之前调用shutdown()。

在关闭函数中尝试以下内容:

m_sock.shutdown(boost::asio::ip::tcp::socket::shutdown_receive);
m_sock.close();

如果要关闭发送和接收,请使用&#34; shutdown_both&#34;而不是&#34; shutdown_receive&#34;。

有趣的是,我在Windows上发现了这个错误,但在没有调用关闭的情况下使用实现时却没有Linux。