Question

I am not sure why I am getting a segmentation fault when I begin an async_write() with a string as a buffer. I have successfully used this function in the past.

Here is the method where I get the segmentation fault:

void StringSocket::sendLine(const string& toWrite)
{
    try
    {
    std::cout << "in StringSocket::sendLine()\n";
    std::cout << "is the socket alive?: " << (bool)s->is_open() << "\n";
    std::cout << "toWrite: " << toWrite;

     //s = asio::ip::tcp::socket* 
     asio::async_write(*this->s,
           asio::buffer(toWrite),
           boost::bind(&StringSocket::MessageSent,
                   this,
                   asio::placeholders::error));
  std::cout << "AFTER: asio::async_write()\n";

    }
    catch (int e)
    {
        std::cout << "ERROR: " << e << "\n";
    }
}

here is what the compiler says:

in main()
in serverTCP::serverTCP()!
in spreadsheet::spreadsheet()
in serverTCP::start_accept()!
in client::client(asio::io_service& io_service, std::string name)
in StringSocket::StringSocket(asio::ip::tcp::socket *_socket)
in client::getSocket()
in StringSocket::underSoc()
in serverTCP::pickSpreadsheet()!
in client::getClientName()
in client::sendToGui(std::string mess)
in StringSocket::beginSend(const string& toWrite, sendCallback callBack, void* payload)
toWrite: Welcome to SS! user: user0000
in StringSocket::ProcessSend()
TextToSend: Welcome to SS! user: user0000
in StringSocket::sendLine()
is the socket alive?: 1
toWrite: Welcome to SS! user: user0000
Segmentation fault
Was it helpful?

Solution 2

If you check the reference for async_write (all the overloads says the same on this subject) it will tell you that the handler function takes two arguments, first the error code and then the length of the sent data.

Your boost::bind call only provides one argument. You still have to tell boost::bind that there is an extra argument that will be filled in later. You do that with the placeholder argument, boost::asio::placeholders::bytes_transferred:

So change it to e.g.

boost::bind(&StringSocket::MessageSent,
            this,
            asio::placeholders::error,
            asio::placeholders::bytes_transferred)

OTHER TIPS

asio::async_write(*this->s, asio::buffer(toWrite),...

Note that asio::buffer is just an adapter that doesn't copy its argument. So, in the above line you actually pass a local object as a buffer to the async. operation. Thus, there's a race condition between the toWrite lifespan and the async. operation.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top