boost::asio async_accept 总是出错,error_code.value() 为22,表示参数无效

Posted

技术标签:

【中文标题】boost::asio async_accept 总是出错,error_code.value() 为22,表示参数无效【英文标题】:boost::asio async_accept always occur a error, error_code.value() is 22, which means invalid argument 【发布时间】:2017-06-18 04:14:56 【问题描述】:

我用过 boost::asio,有 8 个线程

boost::asio::io_service ios;


boost::asio::ip::tcp::acceptor(ios);
boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), port);
acceptor.open(endpoint.protocol());
acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
acceptor.listen();

LocalTcpServer::getInstance()->initialize(ios, acceptor, pool);

boost::thread_group th_group;
for(i=0; i< 8; i++)
th_group.add_thread(new boost::thread(boost::bind(&boost::asio::io_service::run, &ios)));
th_group.join_all();





session::start()

    socket.async_read_some(boost::asio::buffer(buffer), m_strand.wrap(boost::bind(&session::handle_read, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)))

session::handleread(boost::system::error_code &e, size_t byteTrans)

    if(e || byteTrans == 0 )
    
         socket.shutdown(...)
         //socketRelease close the socket and delete this
         timeInfo->timer->async_wait(boost::bind(socketRelease(), ...);
    
    else
    
       //deal with data whit pool;  
    

    socket.async_read_some(.....);










LocaltcpServer::initialize(ios, acceptor, pool) 
   //init, pool is inherit from threadpool, used in handle read to deal with     receive data
   ...; 
   startaccept(); 

LocalTcpServer::Accept()

     session* pSession = new session(acceptor->get_io_service, pool);
     acceptor.async_accept(session->socket, boost::bind(handle_accept, this, pSession, boost::asio::placeholder::error))


LocalTcpServer::handle_accept(boost::system::error_code& e; ... );

    if(e)
    
        //when app run sometime(serveral hours or days, e has always error 22, means invalid argument )
        LOG_ERROR << e.message() << e.value();
        delete newSession;
        accept();
    
    else
    
         session.start();
         accept();
    

该应用程序一开始工作正常,但有时可能几个小时,1 或 2 天后,错误来了,hander_accpte 总是得到一个错误,无效的参数。所以,没有新的连接,

套接字连接几乎是10000,文件打开限制是65535, 我已经使用 netstat 检查套接字是否正常关闭,没有套接字没有关闭 我想知道为什么会发生错误,我该如何解决它, 或者如果我的代码有一些错误? 我希望我能清楚地描述这个问题。谢谢。

【问题讨论】:

m_strand.wrap() 是否将您的回调包装在一个线程中?出于某种原因,对于可以在单个线程上处理 50k 连接而不会降低性能的库来说,8 个线程听起来很多。 asio 例程应该从与 io_service::run() 相同的线程运行;我认为你遇到了某种比赛条件。 很难判断错误来自哪里...如果侦听套接字也失败了,主要嫌疑人之一是 dhcp。接口的 IP 地址可能已更改。在这种情况下,绑定到该接口的所有打开的套接字都变得无效并且必须关闭,包括侦听套接字,然后必须使用新的套接字重新启动侦听。 我发现当错误发生时,监听消失了。例如,我使用 netstat -nat | grep 1234 显示连接,没有listen 线路,线路的localAddress 为127.0.0.1:1234,状态为listen。但是当它正确运行时你可以看到这条线。但是之前建立了一些连接,一段时间后,连接减少到零。我很好奇为什么听不见了?如果我创建一个新的接受者来监听,它会起作用吗?? 【参考方案1】:

如果监听套接字也失败了,那么主要的嫌疑人之一就是 dhcp。接口的 IP 地址可能已更改。

在这种情况下,绑定到该接口的所有打开的套接字都变得无效并且必须关闭,包括正在侦听的套接字,然后必须使用新的套接字重新开始侦听。

【讨论】:

以上是关于boost::asio async_accept 总是出错,error_code.value() 为22,表示参数无效的主要内容,如果未能解决你的问题,请参考以下文章

boost::asio::ip::tcp::acceptor 在使用 async_accept 接收连接请求时终止应用程序

boost::asio async_accept 杀死 ioservice

Boost asio async_accept 在 Windows 下工作,但在 FreeBSD 下失败。怎么了?

Boost asio 获取“错误代码:125 操作已取消”[关闭]

将 Boost.Log 与 Boost.Asio 服务一起使用

使用 boost::asio::async_wait_until 和 boost::asio::streambuf