How to read a fix-sized packet using boost asio?

前端 未结 3 427
醉梦人生
醉梦人生 2021-01-06 17:44

I am doing a synchronous read/write using boost-asio. The data is coming in binary format, without boundary, the length information is encoded in the packet

3条回答
  •  借酒劲吻你
    2021-01-06 17:55

    I work on a program wich send different data with different size. I use a fixed header of 8 byte to encode the size, then, I add the data :

     enum { header_length = 8 }; //const header length
    

    I get the size (m_outbound_data is a std::string == a serialized object)

    //give header length    
    std::ostringstream header_stream
    header_stream << std::setw(header_length) //set a field padding for header  
                  << std::hex                 //set next val to hexadecimal
                  << m_data_out.m_outbound_data.size(); //write size in hexa
    
    m_data_out.m_outbound_header = header_stream.str(); //m_outbound_head == size in hexa in a std::string
    
          //m_outbound_header = [ 8 byte size ] 
          //m_outbound_data = [ serialized data ]
    
          //write all data in the std::vector and send it
          std::vector buffer;
          buffer.push_back(boost::asio::buffer(m_data_out.m_outbound_header));
          buffer.push_back(boost::asio::buffer(m_data_out.m_outbound_data));
    

    And for reading, you need to read in 2 time : 1st read 8 byte to get the size, then read the data in a vector and deserialize into object :

     struct network_data_in {   
      char m_inbound_header[header_length]; //size of data to read  
      std::vector m_inbound_data; // read data    
    };
    

    I use this struct to get data, call read on the m_inbound_header to fill the buffer with size first, then, in the handle :

    //get size of data
    std::istringstream is(std::string(m_data_in.m_inbound_header, header_length));
    std::size_t m_inbound_datasize = 0;
    is >> std::hex >> m_inbound_datasize;
    m_data_in.m_inbound_data.resize(m_inbound_datasize); //resize the vector
    

    then call again read with the m_inbound_data on buffer, this result of reading exactly the data sent In the second handle_read you juste have to deserialize the data :

    //extract data
    std::string archive_data (&(m_data_in.m_inbound_data[0]),m_data_in.m_inbound_data.size());
    std::istringstream archive_stream(archive_data);
    boost::archive::text_iarchive archive(archive_stream);
    archive >> t; //deserialize
    

    Hope that help you !

提交回复
热议问题