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

Posted

技术标签:

【中文标题】Boost asio async_accept 在 Windows 下工作,但在 FreeBSD 下失败。怎么了?【英文标题】:Boost asio async_accept works under Windows but fails under FreeBSD. What's wrong? 【发布时间】:2017-06-15 10:32:27 【问题描述】:

编辑:看起来这不是我的代码,而是构建环境。这既好又坏,因为现在我知道代码没问题,但不知道如何调试环境。这里有什么建议吗?请记住,我在这台计算机上没有管理员权限。

我一直在尝试让简单的代码在 FreeBSD 下工作。这是从 Boost 1.64 asio 对 async_accept 的调用,它不起作用。相同的代码在 Windows 下运行良好,但在 FreeBSD 下它接受客户端连接(客户端上的连接调用成功)但从不调用其处理程序。甚至不知道如何解决这个问题。 (请注意,与其他相关问题不同,我确实致电 io_service.run())请帮助。

显示问题的自包含代码:

#include <iostream>
#include <boost/bind.hpp>
#include <boost/asio.hpp>

namespace asio = boost::asio;
namespace ph = asio::placeholders;
namespace sys = boost::system;
using asio::ip::tcp;

static void accept_handler(const sys::error_code& error)

    // THIS IS NEVER CALLED UNDER FREEBSD
    if (error)
        std::cout << "failed to connected to server" << std::endl;
    else
        std::cout << "connected to server" << std::endl;


int main(int argc, char* argv[])

    if (argc < 3)
    
        std::cerr << "Usage: accept_test <port> <1 for async and 0 for sync accept>" << std::endl;
        return 1;
    

    asio::io_service io_service;
    tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), atoi(argv[1])));

    std::cout << "waiting for server connection ";
    tcp::socket sock(io_service);

    if (argv[2][0] == '1')
    

        //THIS WORKS UNDER WIN BUT DOESN'T CALL HANDLER UNDER FREEBSD
        std::cout << "using async accept..." << std::endl;
        acceptor.async_accept(sock, boost::bind(&accept_handler, ph::error));
    
    else
    
        //THIS WORKS FINE UNDER BOTH WIN AND FREEBSD
        std::cout << "using sync accept..." << std::endl;
        sys::error_code error;
        acceptor.accept(sock, error);
        if (error)
            std::cout << "failed to connected to server" << std::endl;
        else
            std::cout << "connected to server" << std::endl;
    

    io_service.run();
    return 0;

【问题讨论】:

致最接近的选民:这是一个很好的问题,与其他人相关并且与 SSCCE 相关。没有比这更相关的了。 【参考方案1】:

我怀疑您的构建环境存在问题。同步和异步都适用:

FreeBSD 12.0-CURRENT(通用)#0 r319859:2017 年 6 月 12 日星期一 19:37:22 UTC

FreeBSD clang 版本 4.0.0(tags/RELEASE_400/final 297347)(基于 LLVM 4.0.0)

Target: x86_64-unknown-freebsd12.0
Thread model: posix
InstalledDir: /usr/bin

Boost 1.64.0(来自端口)

使用

# clang++ -std=c++11 -o test -isystem /usr/local/include/ ./test.cpp -L /usr/local/lib -lboost_system

生成的二进制文件:

# ldd test
test:
        libboost_system.so.1.64.0 => /usr/local/lib/libboost_system.so.1.64.0 (0x80083c000)
        libc++.so.1 => /usr/lib/libc++.so.1 (0x800a3f000)
        libcxxrt.so.1 => /lib/libcxxrt.so.1 (0x800d06000)
        libm.so.5 => /lib/libm.so.5 (0x800f24000)
        libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x801151000)
        libc.so.7 => /lib/libc.so.7 (0x801367000)
        libthr.so.3 => /lib/libthr.so.3 (0x80172e000)

构建环境的粗略说明:

vagrant init freebsd/FreeBSD-12.0-CURRENT
vagrant up --provider virtualbox
vagrant ssh
su
pkg install lang/clang-devel
pkg install devel/boost-all
# copy test.cpp

【讨论】:

增加了在virtualbox上重现测试环境的说明【参考方案2】:

我的猜测是您运行的是 Boost 1.57 或更早版本。 kqueue 反应器在某些版本中被破坏,与您所看到的症状完全相同。您应该升级到更高版本。对我来说,它适用于 FreeBSD 上的 1.59。

【讨论】:

我使用 boost 1.64 @Paul 您的构建环境问题可能是您的包含搜索路径中有较早版本的 boost。检查编译器的 -I 选项,然后查看这些目录以确认 boost 版本。还要检查是否有人在 /usr/include 下安装了早期版本的 boost。

以上是关于Boost asio async_accept 在 Windows 下工作,但在 FreeBSD 下失败。怎么了?的主要内容,如果未能解决你的问题,请参考以下文章

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

boost::asio async_accept 杀死 ioservice

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

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

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

Boost::Asio : io_service.run() vs poll() 或者我如何在主循环中集成 boost::asio