2

I was using boost version boost 1_64_0 to run a Tcp server in a seprate thread

This was the code for the server.

https://www.boost.org/doc/libs/1_52_0/doc/html/boost_asio/example/echo/async_tcp_echo_server.cpp

in the Main loop i could spawn a new thread like this.

int main()
{

// Run the boost echo server as a different thread
boost::asio::io_service io_service;
server server1(io_service, 1980);   
boost::thread t(boost::bind(&io_service::run, &io_service));    

// when about to close the program
io_service.stop(); // stop the server
t.join();
}

Now i have changed the boost version to boost_1_73_0 and i am using this example to create a server

https://www.boost.org/doc/libs/1_71_0/doc/html/boost_asio/example/cpp11/echo/async_tcp_echo_server.cpp

how do to create a new thread ?

The existing code to create a new thread gives error.

  1. io_service: left of :: must be a class/struct/union

  2. run : undeclared identifier

Summit
  • 2,112
  • 2
  • 12
  • 36

1 Answers1

1

In &io_service::run, io_service is not a type but the local variable by that name.

Starting from https://www.boost.org/doc/libs/1_74_0/doc/html/boost_asio/example/cpp11/echo/async_tcp_echo_server.cpp

    io_context.run();

Needs to be like

    std::thread t([&] { io_context.run(); });
    // ...
    t.join();

Or if you insist:

    std::thread t(boost::bind(&boost::asio::io_context::run, &io_context));

I would use a thread_pool to shortcut all the complexities¹:

    boost::asio::thread_pool io(1);

    server s(io.get_executor(), std::atoi(argv[1]));

    // ...
    io.join();

A trivial edit to the class interface is required (see e.g. Boost 1.70 io_service deprecation)

Live On Coliru

//
// async_tcp_echo_server.cpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

#include <boost/asio.hpp>
#include <boost/bind/bind.hpp>
#include <cstdlib>
#include <iostream>
#include <memory>
#include <utility>

using boost::asio::ip::tcp;

class session : public std::enable_shared_from_this<session> {
  public:
    session(tcp::socket socket) : socket_(std::move(socket)) {}

    void start() { do_read(); }

  private:
    void do_read() {
        auto self(shared_from_this());
        socket_.async_read_some(
            boost::asio::buffer(data_, max_length),
            [this, self](boost::system::error_code ec, std::size_t length) {
                if (!ec) {
                    do_write(length);
                }
            });
    }

    void do_write(std::size_t length) {
        auto self(shared_from_this());
        boost::asio::async_write(
            socket_, boost::asio::buffer(data_, length),
            [this, self](boost::system::error_code ec, std::size_t /*length*/) {
                if (!ec) {
                    do_read();
                }
            });
    }

    tcp::socket socket_;
    enum { max_length = 1024 };
    char data_[max_length];
};

class server {
  public:
    template <typename Executor>
    server(Executor ex, short port)
            : acceptor_(ex, tcp::endpoint(tcp::v4(), port)) {
        do_accept();
    }

  private:
    void do_accept() {
        acceptor_.async_accept(
            [this](boost::system::error_code ec, tcp::socket socket) {
                if (!ec) {
                    std::make_shared<session>(std::move(socket))->start();
                }

                do_accept();
            });
    }

    tcp::acceptor acceptor_;
};

int main(int argc, char* argv[]) {
    try {
        if (argc != 2) {
            std::cerr << "Usage: async_tcp_echo_server <port>\n";
            return 1;
        }

        boost::asio::thread_pool io(1);

        server s(io.get_executor(), std::atoi(argv[1]));

        // ...
        io.join();
    } catch (std::exception& e) {
        std::cerr << "Exception: " << e.what() << "\n";
    }
}

¹ see e.g. Should the exception thrown by boost::asio::io_service::run() be caught?

sehe
  • 374,641
  • 47
  • 450
  • 633