Search code examples
c++boost

how to cast boost byte array to a structure


I am receiving incoming UDP packets in a particular structure format as bytes.

struct Packet_ {
unsigned char header;
unsigned char command;
unsigned char timecode1;
};

Now in the handle receive function i want to convert the incoming byte data to the packet structure.

boost::array<char, 1024> recv_buffer_; // Data would be received in this array should this be a char or byte array ?

void handle_receive(const boost::system::error_code& error,
        std::size_t bytes_transferred)
{
     std::string str(recv_buffer_.c_array(), bytes_transferred); // This works can i cast this to the structure ?
     Packet_ packet = (Packet_)recv_buffer_.c_array(); // Does not work



}

Also how do we cast the recceived array to the structure ?


Solution

  • I'd reverse the question. How can you read into your data structure?

    struct X {
        boost::asio::io_context ioc;
        tcp::socket s{ioc};
        std::array<Packet, 32> packets;
    
        void demo() {
            s.connect({{},8989});
    
            s.async_read_some(
                boost::asio::buffer(packets),
                std::bind(&X::handle_read, this, _1, _2));
        }
    
        void handle_read(error_code ec, size_t transferred)
        {
            std::cout << "Received " << transferred << " bytes ("
                      << ec.message() << ")\n";
            std::cout << "First packet "           //
                      << packets[0].header << " "  //
                      << packets[0].command << " " //
                      << packets[0].timecode1      //
                      << std::endl;
        }
    };
    

    Live demo:

    Live On Coliru

    #include <boost/asio.hpp>
    #include <boost/beast.hpp>
    #include <iostream>
    using boost::asio::ip::tcp;
    using boost::system::error_code;
    using namespace std::placeholders;
    
    struct Packet
    {
        unsigned char header;
        unsigned char command;
        unsigned char timecode1;
    };
    
    struct X {
        boost::asio::io_context ioc;
        tcp::socket s{ioc};
        std::array<Packet, 32> packets;
    
        void demo() {
            s.connect({{}, 8989});
    
            s.async_read_some(
                boost::asio::buffer(packets),
                std::bind(&X::handle_read, this, _1, _2));
    
            ioc.run_for(std::chrono::seconds(1));
        }
    
        void handle_read(error_code ec, size_t transferred)
        {
            std::cout << "Received " << transferred << " bytes ("
                      << ec.message() << ")\n";
            std::cout << "First packet "           //
                      << packets[0].header << " "  //
                      << packets[0].command << " " //
                      << packets[0].timecode1      //
                      << std::endl;
        }
    };
    
    int main() {
        X x;
        x.demo();
    }
    

    With a server:

    netcat -l -p 8989 -w 1 <<< "ABCDEF"& sleep 1; ./a.out
    

    Prints

    Received 7 bytes (Success)
    First packet A B C