Передача изображения с клиента на сервер при помощи boost asio и OpenCV

Пытаюсь передать изображение с клиента на сервер при помощи asio и OpenCV. В итоге при вызове функции async_read() на сервере, данная функция не вызывает handler и просто ьесконечно читает данные с клиента. Может кто подсказать, как правильно написать функцию async_read(), чтобы она прочитала все байты изображения из сокета и вызвала handler. Код клиента:

void async_read(boost::asio::streambuf& streambuf, boost::asio::ip::tcp::socket& socket)
{
    boost::asio::async_read(socket, streambuf, [&](boost::system::error_code errorCode, std::uint16_t bytes_transfered){
        std::istream istream(&streambuf);
        std::cout << istream.rdbuf();
        streambuf.consume(bytes_transfered);
        socket.close();
    });
}
void async_write(boost::asio::ip::tcp::socket& socket, std::vector<uchar>& photo_bytes)
{
    boost::asio::async_write(socket, boost::asio::buffer(photo_bytes), [&](boost::system::error_code errorCode, std::uint16_t bytes_transfered){
       std::cout << "Bytes transfered to server: " << bytes_transfered << std::endl;
    });
}
int main(int argc, char* argv[]) {
    std::string server = argv[1];
    std::string port = argv[2];
    std::string path_to_input_ph = argv[3];
    std::string path_to_output_ph = argv[4];
    boost::asio::io_context ioContext;
    boost::asio::ip::tcp::resolver  resolver(ioContext);
    boost::asio::ip::tcp::resolver::results_type  results = resolver.resolve(server, port);
    // обработка изображения перед отправкой
    cv::Mat srcmat;
    std::vector<uchar> ImgBuf = {};
    std::vector<int> quality_params{95, 95};
    srcmat = cv::imread(path_to_input_ph);
    cv::imencode(".jpg", srcmat, ImgBuf, quality_params);
    boost::asio::ip::tcp::socket socket(ioContext);
    boost::asio::async_connect(socket, results, [&](boost::system::error_code errorCode, boost::asio::ip::tcp::endpoint const& endpoint){
        async_write(socket, ImgBuf);
    });
    boost::asio::streambuf streambuf;
    async_read(streambuf, socket);
    ioContext.run();
    return 0;
}

Код сервера:

class Session : public std::enable_shared_from_this<Session> {
public:
    Session(boost::asio::ip::tcp::socket &&socket) :
            _socket(std::move(socket)) {

    }
    void start_session() {
        std::cout << "Session started" << std::endl;
        async_read();
    }

private:
    boost::asio::ip::tcp::socket _socket;
    std::vector<uchar> ImgBuf;
    cv::Mat mat;

    void async_read() {
        std::cout << "Async_read: started receiving bytes" << std::endl;
        boost::asio::async_read(_socket, boost::asio::dynamic_buffer(ImgBuf, 65000), [&, self = shared_from_this()](boost::system::error_code errorCode,
                                                                                    std::uint16_t bytes_transfered) {
            if (!errorCode) {
                std::cout << "Bytes received: " << bytes_transfered << std::endl;
                self->mat = cv::imdecode(ImgBuf, 95);
                std::vector<int> compression_params;
                compression_params.push_back(95);
                compression_params.push_back(100);
                if(!ImgBuf.empty())
                cv::imwrite("/home/crestonix/CLionProjects/Gray_Image.jpg", mat, compression_params);
                else
                {
                    std::cout << "Error!";
                }
                async_write();

            }
        });
    }

    void async_write() {
        std::cout << "Async_write: started transfering bytes" << std::endl;
        boost::asio::async_write(_socket, boost::asio::buffer("Ty for image!"),
                                 [&](boost::system::error_code errorCode, std::uint16_t bytes_transfered) {
                                     if (!errorCode)
                                         std::cout << "Bytes delivered" << bytes_transfered << std::endl;
                                     _socket.close();

                                 });
    }
};

class Server {
public:
    Server(boost::asio::io_context &io_context, std::uint16_t port) :
            _ioc(io_context) {
        std::cout << "Server constructed" << std::endl;
        _acceptor.emplace(_ioc, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port));
    }

    void async_accept() {
        _socket.emplace(_ioc);
        _acceptor->async_accept(*_socket, [&](boost::system::error_code errorCode) {
            std::cout << "Connection accepted" << std::endl;
            auto session = std::make_shared<Session>(std::move(*_socket));
            session->start_session();
            async_accept();
        });
    }

private:
    boost::asio::io_context &_ioc;
    std::optional<boost::asio::ip::tcp::acceptor> _acceptor;
    std::optional<boost::asio::ip::tcp::socket> _socket;
};

int main() {
    boost::asio::io_context io_context;
    Server server(io_context, 15001);
    server.async_accept();
    io_context.run();
    return 0;
}

Ответы (0 шт):