Boost asio async_accept works under Windows, but does not work under FreeBSD. What's wrong?

EDIT: It looks like this is not my code, but the build environment. This is good and bad, because now I know that the code is fine, but I don’t know how to debug the environment. Any suggestions here? Keep in mind that I do not have administrator rights on this computer.

I'm stuck trying to make code simple under FreeBSD. This is a call async_acceptfrom Boost 1.64 asio that is not behaving. The same code works fine under Windows, but under FreeBSD it accepts a client connection (the connection call on the client side succeeds), but never calls its handler. Not even sure how to approach this. (Please note that unlike other related issues, I call io_service.run()). Please, help.

Standalone code that shows the problem:

#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;
}
+4
source share
2 answers

I suspect the problem is with your build environment. Both synchronization and asynchronous operation:

  • FreeBSD 12.0-CURRENT (GENERIC) # 0 r319859: Mon Jun 12 19:37:22 UTC 2017
  • FreeBSD clang version 4.0.0 (tags / RELEASE_400 / final 297347) (based on LLVM 4.0.0)

    Target: x86_64-unknown-freebsd12.0
    Thread model: posix
    InstalledDir: /usr/bin
    
  • Boost 1.64.0 (from ports)

Built using

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

The resulting binary file:

# 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)

enter image description here

Rough instructions for building env:

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
+2
source

I assume that you are using Boost 1.57 or earlier. The kqueue reactor was broken in some versions with exactly the same symptoms that you see. You must upgrade to a later version. It works fine with 1.59 on FreeBSD for me.

+2

Source: https://habr.com/ru/post/1679333/


All Articles