Повышение с использованием async_write отправляет странные данные - PullRequest
0 голосов
/ 09 июня 2018

Я пытаюсь разработать простую программу чата с использованием Boost.Я столкнулся со странной ситуацией.Я использую netcat для прослушивания определенного порта, пока запускаю программу, которая отправляет простой текст.Соединение установлено, но текст перепутан.На самом деле вместо целой строки я иногда получаю один случайный символ или два.Я пишу код ниже:

#include "lib/client.h"
#include <boost/asio.hpp>
#include <boost/asio/io_service.hpp>
#include <iostream>
#include <thread>
#include <string>


int main(int argc, char* argv[]){
    if(argc != 3){
        std::cout << "Wrong use. After specifying executable, add host and port\n";
        return 0;
    }
    boost::asio::io_service io_service;
    boost::asio::ip::tcp::resolver resolver(io_service);
    auto endpoint = resolver.resolve({argv[1],argv[2]});
    Client c(io_service, endpoint);
    std::thread t([&io_service](){ io_service.run();});
    std::string text = "Welcome host!";
    c.add_msg_to_deque(text);
    t.join();
    c.close();


    return 0;
}

А вот методы клиента:

#include "../lib/client.h"
#include <boost/asio.hpp>
#include <boost/asio/io_service.hpp>
#include <boost/array.hpp>
#include <deque>
#include <iostream>
#include <string>

void Client::connect(boost::asio::ip::tcp::resolver::iterator endpoint){
    boost::asio::async_connect(socket, endpoint,
        [this](boost::system::error_code ec, boost::asio::ip::tcp::resolver::iterator)
        {
          if (!ec)
          {
          }
        });
}

void Client::close()
{
    ios.post([this]() { socket.close(); });
}

void Client::add_msg_to_deque(const std::string& msg){
    ios.post([this,msg](){
         write_msg_deque.push_back(msg);
         send_msg();
     });
}

void Client::send_msg(){
    boost::array<char,128> buf;
    std::string temp_string = write_msg_deque.front();
    std::copy(temp_string.begin(),temp_string.end(),buf.begin());
    boost::asio::async_write(socket, boost::asio::buffer(buf,temp_string.size()),[this](boost::system::error_code ec, std::size_t){
        if(!ec){
            write_msg_deque.pop_front();
            if(!write_msg_deque.empty())
                send_msg();
        }
        else{
            socket.close();
        }
    });
}

1 Ответ

0 голосов
/ 09 июня 2018

Вы используете async_write с локальными данными, это плохая идея.async_write возвращается немедленно.После вызова async_write ваш метод send_msg завершается, поэтому локальные данные (массив buf) уничтожаются перед отправкой вашего сообщения.Вы можете использовать синхронную версию функций ввода-вывода для отправки данных или сохранить buf в качестве члена вашего класса, чтобы обеспечить наличие данных до успешной отправки данных.

...