boost.asio async_receive никогда не разрешать - PullRequest
0 голосов
/ 20 сентября 2018

Я пытаюсь узнать, как работает asio, внедрив эхо-сервер.Но это никогда ничего не отображает!

Это мой код (, пожалуйста, не обращайте внимания на утечку ресурсов ):

#include<boost/asio.hpp>
#include<cstdio>

boost::asio::io_service ioService;

void echo(boost::asio::ip::tcp::socket* socket) {
    char* buf = new char[1024];
    socket->async_receive(boost::asio::buffer(buf, 1023), [buf, socket](auto ec, auto s) {
        if (ec) {
            std::printf("read failed: %s!\n", ec.message().data());
        }
        else
        {
            buf[s] = '\0';
            std::printf("read:%s!\n", buf);
            socket->async_send(boost::asio::buffer(buf, s), [socket](auto ec, auto s) {
                if (ec) {
                    std::printf("write failed: %s!\n", ec.message().data());
                }
                else {
                    echo(socket);
                }
            });
        }
    });
}

void accept(boost::asio::ip::tcp::acceptor& acceptor) {
    auto socket = new boost::asio::ip::tcp::socket{ ioService };
    acceptor.async_accept(*socket, [socket](auto ec) {
        if (ec) {
            std::printf("accept failed:%s!\n", ec.message().data());
        }
        else {
            std::printf("accept %s!", socket->remote_endpoint().address().to_string().data());
            echo(socket);
        }
    });
}

int main() {
    try {
        boost::asio::ip::tcp::acceptor acceptor{ ioService, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), 8000) };
        accept(acceptor);
        while (true)
        {
            ioService.poll();
        }
    }
    catch (std::exception&e) {
        std::printf("error: %s\n", e.what());
    }
}

Я использую Java TCP Client (который яуже протестировал с эхо-сервером Java TCP) для подключения и отправки сообщений на этот сервер.Единственное, что работает - это функция принятия.Где я могу ошибиться?

1 Ответ

0 голосов
/ 21 сентября 2018

Проблема в том, что:

    while (true)
    {
        ioService.poll();
    }

Вам нужно удалить цикл while и использовать метод "run":

     ioService.run();

Фактическая проблема заключается в том, что вы должны вызватьметод " restart " (или более старый метод reset для более старых версий asio, что имеет место в вашем коде) перед повторным вызовом poll.Другая проблема с циклом состоит в том, что когда нечего делать, процессор, на котором он работает, будет на 100%, так как он находится в жестком цикле, ничего не делая ... Если вы используете метод "run", процессор будет использовать0%, когда делать нечего.

например,

while (true)
{
    ioService.poll();
    ioService.reset();
}

Цитировать документацию ASIO:

Эта функция должна вызываться до любой секунды илиболее поздний набор вызовов функций run (), run_one (), poll () или poll_one (), когда предыдущий вызов этих функций возвращался из-за остановки io_context или отсутствия работы.После вызова метода restart () функция stop () объекта io_context вернет false.

...