Search code examples
c++asio

How to properly store asio connections and reuse them? (non-boost)


I am trying to understand basic ASIO (non-boost) but I am having issues understanding how you can store sockets to reuse them later. I was looking at this post: Storing boost sockets in vectors and tried to reimplement it in my code:

#include <iostream>
#include <string>
#include <vector>
#include <asio.hpp>
#include <memory>

std::vector<std::shared_ptr<asio::ip::tcp::socket>> clients;

int main() {
    std::cout << "Starting server..." << "\n";

    try {
        asio::io_context io_context;
        asio::ip::tcp::acceptor acceptor(io_context, asio::ip::tcp::endpoint(asio::ip::tcp::v4(), 6666)); /* Ports below 1025 doesn't work due to permission problem? */

        for (;;) {
            asio::ip::tcp::socket socket(io_context);
            acceptor.accept(socket);
   
            std::string message = std::to_string(clients.size());
            asio::error_code ignored_error;
            asio::write(socket, asio::buffer(message), ignored_error);

            std::shared_ptr<asio::ip::tcp::socket> newconn = std::make_shared<asio::ip::tcp::socket>(std::move(socket)); 
            clients.push_back(newconn);

            /* This does not work */
            for(auto &x : clients) {
                std::string msg = "hello";
                asio::write(x, asio::buffer(msg), ignored_error);
            }

        }
        
    } catch (std::exception &e) {
        std::cerr << e.what() << std::endl;
    }

    return EXIT_SUCCESS;
}

But the code snippet for looping over the clients does not seem to work. Am I implementing this incorrectly or is my understanding of shared_ptr's just too poor?

Question: how can I store asio sockets in a vector and reuse them later to send messages?


Solution

  • It's strange that this line works: asio::write(socket, asio::buffer(message), ignored_error); because you moved a socket before std::shared_ptr<asio::ip::tcp::socket> newconn = std::make_shared<asio::ip::tcp::socket>(std::move(socket)); and later tried to use it. In a range based for you get x which is reference to a shared_ptr<socket>. I think you should use asio::write(*x, asio::buffer(message), ignored_error); if function write uses socket and not shared_ptr<socket>.