我正在做同步使用boost-asio进行读取/写入。数据以二进制格式进入,没有边界,长度信息以数据包格式编码。所以以指定的大小阅读是很重要的。 ip::tcp::iostream
能做到吗?有人可以提供一个例子吗?谢谢。如何使用boost asio读取修订大小的数据包?
回答
我在一个程序上工作,它发送不同大小的数据。我用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时间看:1读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,正好读这个结果的数据发送 在你探微有反序列化数据的第二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
希望对你有所帮助!
+1好的答案,这是我的建议。修改您的协议以包含修复长度头。如果你不能修改你的协议,请在问题中注明。 – 2012-02-19 15:36:54
TCP是基于流的协议。这意味着无论你读什么只是一个字节流。 我们来看一个例子:你有一个固定大小的消息,并通过TCP发送它。另一端的程序如何读取整个消息?有两种方法,一种是用控制字符包围消息(例如,STX开始,ETX结束)。在开始时,程序会在STX之前丢弃任何字符,然后将任何其他字符读入消息缓冲区,直到遇到ETX。
另一种方法是在一个固定大小的头(这显然是你的情况)中编码消息长度。所以你可以做的最好的事情是找出读取消息长度的方法,解析它并相应地读取其余的字节。
我知道你需要长度信息,这是给定的。不清楚的是在API中指定这个长度(我想要读取的字节数)。 – Oliver 2012-02-18 10:32:43
@Oliver您的评论没有意义。需要读取的字节数在API中有详细记录['boost :: asio :: read'](http://www.boost.org/doc/libs/1_48_0/doc/html/boost_asio/reference/read/ overload1.html) – 2012-02-19 15:39:24
简单:
boost::asio::read(socket, buffers, boost::asio::transfer_exactly(your_fixed_size));
- 1. C++ Boost asio获取数据大小?
- 2. 为什么boost :: asio :: read缓冲区的数据大小小于读取大小?
- 3. 从boost asio udp socket读取特定数据大小
- 4. C++ boost asio tcp socket读取旧数据
- 5. boost asio:异步数据读取
- 6. boost.asio,如何使用asio读取完整的IP数据包
- 7. 当我使用boost :: asio :: async_write发送一些大数据时,使用boost :: asio :: async_write
- 8. boost :: asio :: async_read不读取后续数据包
- 9. 使用boost :: asio :: read_async读取Protobuf对象
- 10. 如何从Boost ASIO streambuf读取?
- 11. 使用boost asio从串口读取最新数据
- 12. BOOST ASIO:如何使用有限的缓冲区大小与async_read_until
- 13. boost asio读取缓冲区
- 14. Boost asio :: async_write发送数千个小包
- 15. 如何获取是否有任何数据可用套接字读取boost :: asio?
- 16. 如何使用boost :: ASIO
- 17. boost asio async_read_some只读数据片
- 18. 如何使用Boost :: asio异步读取到std :: string?
- 19. Boost asio接收指定大小的数据
- 20. BOOST ASIO使用
- 21. Java:使用NIO读取可变大小的数据包
- 22. 的boost :: ASIO,异步读取错误
- 23. 接收使用boost :: ASIO压缩数据
- 24. 如何使用boost :: asio从网络中断中恢复如何使用boost :: asio
- 25. 如何使用boost :: asio查找UDP数据包的目标地址?
- 26. 修改boost :: asio :: socket :: set_option
- 27. Boost asio异步读取然后写入
- 28. 并发读取和async_read_some in boost asio
- 29. C++,boost asio,读取速度慢
- 30. Boost asio绑定读取处理程序
你是什么意思的信息:*长度信息的数据包格式编码*?协议框架通常在应用程序级别完成,我认为你通过考虑数据包而不是数据流来混淆自己。 – 2012-02-19 15:36:01