【问题标题】:Integrating Boost Asio with ZeroMQ, Bad File Descriptor?将 Boost Asio 与 ZeroMQ 集成,文件描述符错误?
【发布时间】:2018-02-05 18:18:15
【问题描述】:

我正在尝试将 Boost Asio 与 ZeroMQ 集成。消息对于第一个连接有效,但程序退出并出现错误 "Bad File Descriptor" 当初始连接结束时。

我正在使用Async Websocket Server 的Boost.Beast 示例代码与客户端建立连接。然后我打开一个 ZMQ 套接字。客户端通过 Websocket 连接向服务器发送消息,消息通过 ZMQ 套接字发送到不同的服务器,服务器将做一些处理,服务器通过 ZMQ 将消息发送回,最后的消息被发送回客户端通过同一个 Websocket 连接。

我正在使用This Code 将 Boost 与 ZMQ 集成。重要性线是

int zfd;
optlen = sizeof (zfd);
zmq_getsockopt (zmq_sock_, ZMQ_FD, &zfd, &optlen);
sock_.assign (boost::asio::ip::tcp::v4(), zfd);

这会从 ZMQ 套接字中获取一个文件描述符,并用 Boost 套接字将它包装起来,这样一切都很好。但是,当调用析构函数时:

sock_.shutdown(boost::asio::ip::tcp::socket::shutdown_both);
sock_.close();
zmq_close (zmq_sock_);  

我收到一个错误,指出存在 Socket operation on a Non-socket,因为似乎套接字已关闭。如果我删除套接字关闭并关闭,我会收到 ZMQ 的Bad File Descriptor 问题。似乎Session Websocket 对象正在部分破坏 Asio-ZMQ 对象。如果我完全删除析构函数,程序不会崩溃,但它不再正常工作。即它不会再通过 ZMQ 发送任何消息。

我已经为这个问题苦苦挣扎了好几天,希望能得到一些帮助。如果有帮助,我的代码将采用 my_zmq_req_client 类并将其集成到 Boost.Beast session 类中。

【问题讨论】:

    标签: c++ boost-asio zeromq


    【解决方案1】:

    链接库我没看过,但是这个片段

    sock_.shutdown(boost::asio::ip::tcp::socket::shutdown_both);
    sock_.close();
    zmq_close (zmq_sock_);  
    

    看起来很可疑,因为sock_.close() 正在干预一个未被它打开的套接字。我建议release asio 端的套接字更有意义,而不是关闭它,以便 ZMQ 可以继续负责创建/销毁。

    sock_.shutdown(boost::asio::ip::tcp::socket::shutdown_both);
    sock_.release();
    zmq_close (zmq_sock_);  
    

    【讨论】:

    • 难以置信。立即修复它。非常感谢!
    • 作为一个有趣的问题,当zfd 几乎肯定是用于管道(而不是网络套接字)时,使用boost::asio::ip::tcp::v4() 是否重要?我猜不是。
    • @bazza 除非您使用特定于协议的接口,例如选项。我不太确定它是关于管道的,这在 OP 给出的上下文中没有什么意义。
    • @bazza 只是一个事后的想法,如果你/真的/只是想问别的东西(给朋友),你可以使用 Posix 描述符包装器来代替:boost.org/doc/libs/1_66_0/doc/html/boost_asio/overview/posix/…
    • @sehe,抱歉,我并不是要暗示管道与 tcp 与 OP 的问题有任何关系。我很确定来自 ZMQ 的 fd 是用于管道的,所以不经意间想知道是否有任何需要与 Boost 匹配。感谢您提供全面的好答案!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-06
    • 2016-05-04
    • 1970-01-01
    • 2011-06-08
    • 1970-01-01
    • 2012-08-11
    相关资源
    最近更新 更多