понимать поведение boost :: asio async_read, когда нечего читать - PullRequest
0 голосов
/ 05 ноября 2018

Я пытаюсь понять, что произойдет с async_read, когда нечего читать.

Например, клиент создает соединение с сервером, затем запускает async_read(), но этот сервер не ожидает отправки чего-либо этому клиенту. Так что же будет? Должен ли я получить EOF?

Updata: Я думаю, что @ user786653 прав. Я сделал простой пример (см. Ниже).

#include <iostream>
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <boost/asio.hpp>

class test{
public:
test(boost::asio::io_service& io_service):_socket(io_service){
}

void handle_connect(){
    std::cout<<"entering test::handle_connect"<<std::endl;
    char reply[128];
        boost::asio::async_read(_socket, boost::asio::buffer(reply, sizeof(reply)),
                            [](boost::system::error_code ec, std::size_t /*length*/){
                std::cout<<"Read result:"<< ec<<" - "<<ec.message()<<std::endl;
            });
}

boost::asio::ip::tcp::socket & socket(){
    return _socket;
}

private:
boost::asio::ip::tcp::socket _socket;
};



int main() {
try {
boost::asio::io_service io_service;
boost::asio::ip::tcp::socket s(io_service);
boost::asio::ip::tcp::resolver resolver(io_service);
    boost::asio::ip::tcp::resolver::query query("127.0.0.1", "8000");
    boost::asio::ip::tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
    boost::asio::ip::tcp::endpoint endpoint = *endpoint_iterator;

test t(io_service);
t.socket().async_connect(endpoint,boost::bind(&test::handle_connect, &t));

io_service.run();
} catch (std::exception& e) {
    std::cerr << "Exception: " << e.what() << "\n";
}
}

1 Ответ

0 голосов
/ 05 ноября 2018

Цитирование из последней (1.68.0) документации :

Эта функция используется для асинхронного чтения определенного количества байтов данных из потока. Вызов функции всегда возвращается немедленно. Асинхронная операция будет продолжаться до тех пор, пока не будет выполнено одно из следующих условий:

  • Поставленные буферы заполнены. То есть переданные байты равны сумме размеров буфера.
  • Произошла ошибка.

Таким образом, ничего не произойдет, пока сервер не закроет соединение (что приведет к ошибке).

Вы можете проверить это сами:

#include <iostream>
#include <boost/asio.hpp>
int main() {
    try {
        boost::asio::io_context io_context;
        boost::asio::ip::tcp::socket s(io_context);
        boost::asio::ip::tcp::resolver resolver(io_context);
        boost::asio::connect(s, resolver.resolve("localhost", "8000"));
        char reply[128];
        async_read(s, boost::asio::buffer(reply, sizeof(reply)), [](boost::system::error_code ec, std::size_t /*length*/) {
                std::cout << "Read result: " << ec << " - " << ec.message() << "\n";
                });
        io_context.run();
    } catch (std::exception& e) {
        std::cerr << "Exception: " << e.what() << "\n";
    }
}

Запустить сервер, который не отвечает на локальный хост-порт 8000 (или изменить код). Например. что-то вроде nc -l 8000 или python -m SimpleHTTPServer. Затем запустите программу и подождите. Ничего не произошло. Теперь остановите сервер, на моем (Windows) компьютере это приводит к:

Read result: system:10054 - An existing connection was forcibly closed by the remote host
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...