我正在做同步使用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