C++ 异步读取的帮助,直到
我在这里记录的函数中实现第三个参数时遇到问题: 我希望能够使用async_read_的第三个参数的回调,直到检测到完整的块何时到达。我的数据包的格式如下C++ 异步读取的帮助,直到,c++,boost-asio,C++,Boost Asio,我在这里记录的函数中实现第三个参数时遇到问题: 我希望能够使用async_read_的第三个参数的回调,直到检测到完整的块何时到达。我的数据包的格式如下 1字节id(数据的语义含义) unsigned int(数据中的字节数,因为某些数据块可以更改大小) 有效载荷 查看文档中的示例代码,我对如何从开始迭代器和结束迭代器中提取字节(更不用说无符号int)感到有点困惑。 我将迭代器实例化为 typedef boost::asio::buffers\u迭代器< boost::asio::strea
- 1字节id(数据的语义含义)
- unsigned int(数据中的字节数,因为某些数据块可以更改大小)
- 有效载荷
typedef boost::asio::buffers\u迭代器<
boost::asio::streambuf::const\u buffers\u type>迭代器代码>
但即使这样,我也不确定那是什么类型,因为我不知道常量缓冲区类型是什么。我查看了文档中的一些链接,发现它是“实现定义的”,但我想我可能是错的。
因此,我的两个具体问题是:
如何使用这两个迭代器读取无符号int
那些迭代器指向什么类型
谢谢 我的消息格式与您的非常相似(16位有效负载长度,8位数据包id/类型,后跟我的有效负载)。我使用了一个3阶段读取和一系列用于处理不同事情的函数指针。我使用boost::asio::async_read一次读取已知数量
这是我的代码的简化版本:
//call this to start reading a packet/message
void startRead(boost::asio::ip::tcp::socket &socket)
{
boost::uint8_t *header = new boost::uint8_t[3];
boost::asio::async_read(socket,boost::asio::buffer(header,3),
boost::bind(&handleReadHeader,&socket,header,
boost::asio::placeholders::bytes_transferred,boost::asio::placeholders::error));
}
void handleReadHeader(boost::asio::ip::tcp::socket *socket,
boost::uint8_t *header, size_t len, const boost::system::error_code& error)
{
if(error)
{
delete[] header;
handleReadError(error);
}
else
{
assert(len == 3);
boost::uint16_t payLoadLen = *((boost::uint16_t*)(header + 0));
boost::uint8_t type = *((boost::uint8_t*) (header + 2));
delete[] header;
//dont bother calling asio again if there is no payload
if(payLoadLen > 0)
{
boost::uint8_t *payLoad = new boost::uint8_t[payLoadLen];
boost::asio::async_read(*socket,boost::asio::buffer(payLoad,payLoadLen),
boost::bind(&handleReadBody,socket,
type,payLoad,payLoadLen,
boost::asio::placeholders::bytes_transferred,boost::asio::placeholders::error));
}
else handleReadBody(socket,type,0,0,0,boost::system::error_code());
}
}
void handleReadBody(ip::tcp::socket *socket,
boost::uint8_t type, boost::uint8_t *payLoad, boost::uint16_t len,
size_t readLen, const boost::system::error_code& error)
{
if(error)
{
delete[] payLoad;
handleReadError(error);
}
else
{
assert(len == readLen);
//passes the packet to the appropriate function for the type
//you could also use a switch statement or whatever
//to get the next packet you must call StartRead again
//personally I choose to do this from the actaul handler
//themselves
handlePacket(type,payLoad,len,error);
}
}
文档中提供了一个示例匹配函数
std::pair<iterator, bool>
match_whitespace(iterator begin, iterator end)
{
iterator i = begin;
while (i != end)
if (std::isspace(*i++))
return std::make_pair(i, true);
return std::make_pair(i, false);
}
无论如何,考虑到您的读取没有被删除,更好的方法是异步读取一些,直到您读取了大小,然后异步读取一些,至少读取一些。您能清楚地说明如何定义数据包结束吗?
template<
typename AsyncReadStream,
typename Allocator,
typename ReadHandler>
void async_read_until(
AsyncReadStream & s,
boost::asio::basic_streambuf< Allocator > & b,
const boost::regex & expr,
ReadHandler handler);