Я использую свой ПК в качестве сервера. Клиент отправляет такие сообщения, как: «PART1: Part2», и сервер выполняет необходимые действия. Я использую boost asio для кода сервера.boost asio async_read: прочитанное сообщение добавляет к себе
void start_read()
{
boost::asio::async_read(socket_, input_buffer_,
boost::asio::transfer_at_least(1),
boost::bind(&tcp_connection::handle_read, shared_from_this(),
boost::asio::placeholders::error));
}
// When stream is received handle the message from the client
void handle_read(const boost::system::error_code& error)
{
if (!error)
{
boost::asio::streambuf::const_buffers_type bufs = input_buffer_.data();
std::string msgstr(boost::asio::buffers_begin(bufs),
boost::asio::buffers_begin(bufs) +
input_buffer_.size());
std::vector<std::string> msgVector;
boost::split(msgVector, msgstr, boost::is_any_of(":"));
messageFromClient_ = msgVector[0];
valueFromClient_ = msgVector[1];
};
сообщения на сервер отправляются каждый второй и в результате выводе, выглядит следующим образом:
PART1:part2a
PART1:part2bPART1:part2b
PART1:part2cPART1:part2cPART1:part2c
PART1:part2dPART1:part2dPART1:part2dPART1:part2d
Это не то, что я хочу. Я не хочу, чтобы включить данные из предыдущего буфера, то есть я хочу это:
PART1:part2a
PART1:part2b
PART1:part2c
PART1:part2d
Я понимаю, что проблема, скорее всего, лежит здесь:
std::string msgstr(boost::asio::buffers_begin(bufs),
boost::asio::buffers_begin(bufs) +
input_buffer_.size());
Однако, я не могу найти правильный код, будет работать в моем случае.
EDIT: Пытался сделать это вместо:
std::istream response_istream(&input_buffer_);
std::string msgstr;
response_istream >> msgstr;
Первые три раза, я получаю то, что мне нужно, но тогда сообщение умножается. Это всегда так:
PART1:part2a
PART1:part2b
PART1:part2c
PART1:part2dPART1:part2d
PART1:part2ePART1:part2e
PART1:part2fPART1:part2fPART1:part2fPART1:part2f
PART1:part2gPART1:part2g
Большое спасибо заранее.
Большое спасибо, Таннер. У меня есть это сейчас: 'boost :: asio :: streambuf :: const_buffers_type bufs = input_buffer_.data();' 'std :: string msgstr (boost :: asio :: buffers_begin (bufs), boost :: asio :: buffers_begin (bufs) + input_buffer_.size()); '' input_buffer_.consume (input_buffer_.size()); это делает его проблемой, как я показал в своем тексте после редактирования, т. е. первые три раза, строка является нормальной, но тогда он выглядит так: PART1: part2aPart1: part2a. Время от времени у меня есть три компонента в строке. Хм .. Спасибо! –
EDIT: Таннер, снова большое спасибо за вашу помощь. Это очень информативно и полезно. Кажется, я знаю, почему это происходит. Клиент отправляет сообщение каждую секунду, и сервер должен совершать некоторые манипуляции, как только будет отправлено сообщение. Но серверу требуется время для выполнения манипуляций, иногда 2 секунды, иногда 3. Таким образом, буфер накапливается с сообщениями, отправленными от клиента. С уважением, –
@IgorTupitsyn TCP - это поток и, следовательно, не имеет определенной границы сообщения. Следовательно, код должен иметь возможность обрабатывать накопленные значения и частичные значения. Например, отправитель может отправить «PART1: part2a», но вызов 'handle_read()' только читает «PAR».В этом [ответе] (http://stackoverflow.com/a/22291720/1053968) приводятся некоторые рекомендации о том, как обрабатывать это для протоколов приложений фиксированного размера или переменной длины. Кроме того, из-за размера полезной нагрузки отключение Nagle, как показано [здесь] (http://stackoverflow.com/a/23871833/1053968), может повысить производительность. –