How to send raw binary data using boost::asio

12,069

Solution 1

#include <boost/asio.hpp>

#include <boost/foreach.hpp>
#include <boost/lexical_cast.hpp>

#include <iostream>

int
main( unsigned argc, char** argv )
{
    if ( argc < 3 ) {
        std::cerr << "usage: " << argv[0] << " host port" << std::endl;
        exit( EXIT_FAILURE );
    }

    boost::array<float, 5> foo = {1.0, 2.0, 3.0, 4.0, 5.0};
    BOOST_FOREACH( const float i, foo ) {
        std::cout << i << std::endl;
    }

    boost::asio::io_service ios;
    boost::asio::ip::tcp::socket socket( ios );
    socket.connect(
            boost::asio::ip::tcp::endpoint(
                boost::asio::ip::address::from_string( argv[1] ),
                boost::lexical_cast<unsigned>( argv[2] )
                )
            );

    const size_t bytes = boost::asio::write(
            socket,
            boost::asio::buffer( foo )
            );
    std::cout << "sent " << bytes << " bytes" << std::endl;
}

compile

bash-3.2$ g++ -I /opt/local/include -L/opt/local/lib -lboost_system -Wl,-rpath,/opt/local/lib array.cc

run

bash-3.2$ ./a.out 127.0.0.1 1234
1
2
3
4
5
sent 20 bytes
bash-3.2$

server

bash-3.2$ nc -l 1234 | hexdump -b
0000000 000 000 200 077 000 000 000 100 000 000 100 100 000 000 200 100
0000010 000 000 240 100                                                
0000014
bash-3.2$

Solution 2

You can send any sort of data through ASIO, just like you can write any sort of data to a file:

T x;  // anything
const char * px = reinterpret_cast<const char*>(&x);  // no type punning, cast-to-char is allowed

boost::asio::async_write(my_socket, boost::asio::buffer(px, sizeof(T)), ...

Or simply write to a file:

std::ofstream f("data.bin");
f.write(px, sizeof(T));

Casting any variable to char* is expressly allowed by the standard, presumably precisely for the reason that you have to be able to serialize binary data to files and sockets etc.

Share:
12,069
Gareth
Author by

Gareth

Updated on June 09, 2022

Comments

  • Gareth
    Gareth almost 2 years

    I'm writing a TCP client using boost::asio. I want to send an array of floats in their binary representation. Does boost provide a nice way to convert data to their binary representation for placement it in a boost::array or something?

    I have used Qt QDataStream in the past and it worked well; I'm sure boost has something equivalent?