如何使用boost asio读取固定大小的数据包
How to read a fix-sized packet using boost asio?
我正在使用boost asio进行同步读/写。数据是以二进制格式来的,没有边界,长度信息以分组格式编码。因此,以指定的尺寸读入是很重要的。ip::tcp::iostream
能做到吗?有人能举个例子吗?谢谢
简单:
boost::asio::read(socket, buffers, boost::asio::transfer_exactly(your_fixed_size));
我使用一个程序发送不同大小的不同数据。我使用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
希望对你有所帮助!
TCP是一个基于流的协议。这意味着,无论你读到什么,都只是一个字节流。让我们考虑一个例子:您有一个固定大小的消息,并通过TCP发送。另一端的程序如何读取整个消息?有两种方法,一种是用控制字符包围消息(例如,开始时的STX和结束时的ETX)。在开始时,程序将丢弃STX之前的任何字符,然后将任何其他字符读取到消息缓冲区,直到遇到ETX为止。
另一种方法是将消息长度编码在固定大小的标头中(显然就是您的情况)。因此,你能做的最好的事情就是找到一种读取消息长度的方法,解析它,并相应地读取剩余的字节。
相关文章:
- 如何使用发送数据包所花费的时间计算两个节点之间的距离?
- pcap_handler回调仅在使用 NPCAP v0.9991 时包含空数据包
- 使用C++将UDP数据包存储在Structure中
- 使用 c++ 捕获传出数据包
- 类数据成员指针的非类型模板参数包无法使用 gcc 编译
- 如何使用 libtins 捕获 HTTPS 数据包
- 如何使用WinPcap发送/注入数据包
- 通过RTP CPP使用FFMPEG库发送视频流时,数据包掉落
- C++ 使用 recvmmsg 丢弃 UDP 数据包
- 使用 Qt 通过蓝牙发送多个原始数据包
- 使用 UDP 协议从 Windows 套接字发送到 Qt 套接字的网络数据包上的结构编码和解码
- 使用ASIO捕获大量UDP数据包
- 使用FFMPEG编写多线程视频和音频数据包
- 使用C++将完整的以太网数据包发送到特定的ip
- C++ - 如何在向量中使用pcap_next_ex存储脱机读取数据包
- 使用标准对数据包流进行适当实现
- 寻求使用 FFmpeg 在 mp4 容器中 h264 编解码器的视频帧.数据包 pts 始终为 0
- 使用SFML验证实时网络上发送的数据包
- 使用 libpcap 读取数据包数据
- 使用libpcap的无线数据包注入