Простая модель клиент-сервер Boost.Asio не возвращает ответ - PullRequest
0 голосов
/ 17 марта 2019

При первой попытке построить мой клиентский сервер на boost.asio ответ сервера на клиента пуст. я не уверен, в чем проблема - буду рад любой помощи.

Код сервера:

const std::string message = "Hi";
        boost::system::error_code ignored_error;
        try
        {
                boost::asio::io_service io_service;
                tcp::endpoint endpoint = tcp::endpoint(tcp::v4(), 12345);
                tcp::acceptor acceptor(io_service,endpoint);
                for (;;){
                        tcp::socket socket(io_service);
                        acceptor.accept(socket);
                   boost::asio::write(socket,boost::asio::buffer(message), ignored_error);
                }

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

Код клиента:

        try{
        boost::asio::io_service io_service;
        tcp::resolver resolver(io_service);
        tcp::resolver::query query(IP, "12345");
        tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
        tcp::socket socket(io_service);
        boost::asio::connect(socket, endpoint_iterator);
        for (;;)
        {
                std::string buf;
                boost::system::error_code error;



                size_t len = socket.read_some(boost::asio::buffer(buf), error);           
                if (error == boost::asio::error::eof)
                        break; // Connection closed cleanly by peer.
                else if (error)
                        throw boost::system::system_error(error); // Some other error.
                std::cout.write(buf.data());
        }
}
catch (std::exception& e)
{
        std::cerr << e.what() << std::endl;
}

1 Ответ

1 голос
/ 17 марта 2019

socket.read_some считывает данные в буфер, который определяется boost::asio::buffer(buf).Размер этого буфера определяется buf.size().В вашем случае std::string пусто, поэтому буфер для чтения байтов пуст.read_some читает 0 байтов и возвращает.

Поскольку сервер всегда отправляет сообщение, состоящее из 2 байтов, вы можете изменить размер buf для хранения 2 байтов:

std::string buf;
buf.resize(2);
boost::system::error_code error;
size_t len = socket.read_some(boost::asio::buffer(buf), error); 
// now read_some reads at most 2 bytes into buf

Поскольку на стороне сервера создается сокет, он отправляет сообщение и уничтожается, вы можете использовать dynamic_buffer + transfer_all + boost::asio::read для чтения сообщения нефиксированной длины:

std::string buf;
size_t len = boost::asio::read (socket,boost::asio::dynamic_buffer(buf),
    boost::asio::transfer_all(),error);
if (len && error == boost::asio::error::eof)
{ 
  // data was read from server and eof is reached
  // do sth with buf
}

boost::asio::read считывает данные до тех пор, пока буфер не будет прочитан полностью или не возникнут некоторые ошибки (например, eof - сокет на стороне сервера был закрыт).Сервер отправляет данные, клиент читает данные, сокет на сервере уничтожается, и клиент получает eof из asio::read.

...