Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/140.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/spring-boot/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 异步读取的帮助,直到_C++_Boost Asio - Fatal编程技术网

C++ 异步读取的帮助,直到

C++ 异步读取的帮助,直到,c++,boost-asio,C++,Boost Asio,我在这里记录的函数中实现第三个参数时遇到问题: 我希望能够使用async_read_的第三个参数的回调,直到检测到完整的块何时到达。我的数据包的格式如下 1字节id(数据的语义含义) unsigned int(数据中的字节数,因为某些数据块可以更改大小) 有效载荷 查看文档中的示例代码,我对如何从开始迭代器和结束迭代器中提取字节(更不用说无符号int)感到有点困惑。 我将迭代器实例化为 typedef boost::asio::buffers\u迭代器< boost::asio::strea

我在这里记录的函数中实现第三个参数时遇到问题: 我希望能够使用async_read_的第三个参数的回调,直到检测到完整的块何时到达。我的数据包的格式如下

  • 1字节id(数据的语义含义)
  • unsigned int(数据中的字节数,因为某些数据块可以更改大小)
  • 有效载荷
查看文档中的示例代码,我对如何从开始迭代器和结束迭代器中提取字节(更不用说无符号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);