如何使用 boost asio 读取固定大小的数据包?

发布于 2025-01-06 22:35:00 字数 129 浏览 0 评论 0原文

我正在使用 boost-asio 进行同步读/写。数据以二进制格式出现,没有边界,长度信息以数据包格式编码。因此,以指定的大小读入很重要。 ip::tcp::iostream 可以吗?有人可以举个例子吗?谢谢。

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 format. So it is important to read in with specified size. Can ip::tcp::iostream do that? Can someone provide an example? Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

尤怨 2025-01-13 22:35:00

简单的:

boost::asio::read(socket, buffers, boost::asio::transfer_exactly(your_fixed_size));

Simple:

boost::asio::read(socket, buffers, boost::asio::transfer_exactly(your_fixed_size));
枯寂 2025-01-13 22:35:00

我正在开发一个发送不同大小的不同数据的程序。我使用 8 字节的固定标头来编码大小,然后添加数据:

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

我得到大小(m_outbound_data 是 std::string == 序列化对象)

//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<boost::asio::const_buffer> 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));

并且为了读取,您需要读取 2 次:第一次读取 8 个字节来获取大小,然后读取向量中的数据并反序列化为对象:

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

我使用此结构来获取数据,调用 m_inbound_header 上的 read 首先用大小填充缓冲区,然后,在句柄中:

//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

然后再次使用缓冲区上的 m_inbound_data 调用 read,读取的结果正是发送的数据
在第二个handle_read中,您只需反序列化数据:

//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

希望对您有帮助!

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<boost::asio::const_buffer> 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<char> 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 !

毅然前行 2025-01-13 22:35:00

TCP 是一种基于流的协议。这意味着您读取的任何内容都只是字节流。
让我们考虑一个例子:您有一条固定大小的消息,并通过 TCP 发送它。另一端的程序如何读取整条消息?有两种方法,一种是用控制字符包围消息(例如开头为 STX,结尾为 ETX)。开始时,程序将丢弃 STX 之前的所有字符,然后将所有其他字符读入消息缓冲区,直到遇到 ETX。

另一种方法是将消息长度编码在固定大小的标头中(这显然是您的情况)。因此,您能做的最好的事情就是找到一种方法来读取消息长度,解析它并相应地读取剩余字节。

TCP is a stream-based protocol. This means that whatever you read is just a stream of bytes.
Let's consider an example: you have a message of a fixed size and you send it over TCP. How can the program at the other end read the entire message? there are two ways, one is to surround you message with control chracters (e.g. STX at start and ETX at end). At the start, the program would discard any chars before STX, then read any other chars into the message buffer until ETX is encountered.

Another way is to encode the message length in a fixed-size header (which apparently is your case). So the best thing you can do is figure out a way to read the message length, parse it and read the remaining bytes accordingly.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文