-
Adding To A char array
Hello,
I have a client /server example that I am trying to modify. The client will send a message to the server and then echo it back to the client.
I want to append a string to the message when it gets to the server (just before it goes to the client)
Here is the original source
doc/html/boost_asio/example/cpp03/echo/async_tcp_echo_server.cpp - 1.55.0
Here is my non working attempt but for some reason I just cant get it to work.
Code:
string sToSend(data_);
sToSend += "<--- this string to append";
//const char cs = sToSend.c_str();
socket_.async_read_some(boost::asio::buffer(sToSend.c_str(), max_length),
boost::bind(&session::handle_read, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
Error:
Code:
/usr/include/boost/asio/detail/buffer_sequence_adapter.hpp|212|error: no matching function for call to ‘boost::asio::mutable_buffer::mutable_buffer(const boost::asio::const_buffers_1&)’|
Original Code
Code:
tcp::socket socket_;
enum { max_length = 1024 };
char data_[max_length];boost::asio::async_write(socket_, boost::asio::buffer(data_, bytes_transferred), boost::bind(&session::handle_write, this, boost::asio::placeholders::error));
Code:
//
// async_tcp_echo_server.cpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2013 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#include <cstdlib>
#include <iostream>
#include <boost/bind.hpp>
#include <boost/asio.hpp>
using boost::asio::ip::tcp;
class session
{
public:
session(boost::asio::io_service& io_service)
: socket_(io_service)
{
}
tcp::socket& socket()
{
return socket_;
}
void start()
{
socket_.async_read_some(boost::asio::buffer(data_, max_length),
boost::bind(&session::handle_read, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
private:
void handle_read(const boost::system::error_code& error,
size_t bytes_transferred)
{
if (!error)
{
boost::asio::async_write(socket_,
boost::asio::buffer(data_, bytes_transferred),
boost::bind(&session::handle_write, this,
boost::asio::placeholders::error));
}
else
{
delete this;
}
}
void handle_write(const boost::system::error_code& error)
{
if (!error)
{
socket_.async_read_some(boost::asio::buffer(data_, max_length),
boost::bind(&session::handle_read, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
else
{
delete this;
}
}
tcp::socket socket_;
enum { max_length = 1024 };
char data_[max_length];
};
-
Well the error message mentions boost::asio::mutable_buffer::mutable_buffer, which suggests that whatever gets passed in should be susceptible to modification.
A string.c_str() fails to meet this requirement.
You need to allocate a char* block of memory, copy your string to it and then free it when you're done.
-
Thank you for the reply. I have been trying to get this to work but so far I cannot.
No matter what I do, the same amount of bytes is returned back to the client as was originally read. What am i doing wrong here?
Code:
void handle_read(const boost::system::error_code& error,
size_t bytes_transferred)
{
// data_ here == "thisisatest"
if (!error)
{
data_[0] = 'X'; // this works
char * cstr;
string str (data_);
str = str + "app";
cstr = new char [str.size()+1];
strcpy (cstr, str.c_str());
// cstr at this point == "Xhisisatestapp"
// sizeof(cstr) == 8 this is not correct
boost::asio::async_write(socket_,
boost::asio::buffer(cstr, sizeof(cstr)), // sizeof(cstr) is not right here I even try to hardcode this to 12 but it did not work either (only 10 bytes returned to client)
boost::bind(&session::handle_write, this,
boost::asio::placeholders::error));
delete cstr;
// original code
// boost::asio::async_write(socket_,
// boost::asio::buffer(data_, bytes_transferred),
// boost::bind(&session::handle_write, this,
// boost::asio::placeholders::error));
}
else
{
delete this;
}
}
-
Well it's either str.size() or strlen(cstr)
It's also
delete [] cstr;
-
Thank you! strlen worked for fixing the size.
I cant thank you enough for your help!
-
is there a better alternative to getting the char* to a string?
They used this (which is great for writing out to the console but I need it in a string variable)
Code:
cout.write(reply, reply_length);
// this works (only because the last line with the substr) but seems more like a hack
Code:
#define SSTR( x ) static_cast< std::ostringstream & >(( std::ostringstream() << std::dec << x ) ).str()
string sReply = SSTR(reply);
sReply = sReply.substr(0, request_length);
This has garbage at the end of it
Code:
stringstream ss;
string sReply;
ss << reply;
ss >> sReply;
-
Use a vector:
std::vector<char> Buf(1024);
// Write to buffer
// Null terminate buffer if boost doesn't
// Now let's add the buffer to the string
MyStr += &Buf[0];
It would be easier if you used boost's streams to do network I/O. I'm sure there must be an example somewhere.