c + +升压ASIO获取数据的大小?(C++ Boost asio get data size?)

2019-09-29 15:38发布

我现在用的升压ASIO图书馆阅读使用TCP的一些数据。 使用后a.accept(*sock); ,如何让第一分组中的客户端发送的大小?

我使用(sock->remote_endpoint().address()).to_string()来获得用户的IP地址,所以我想必须有一个类似的简单方式来获得数据包的大小,对不对?

Answer 1:

在应用层面,它往往是更为有用知道目前可供读取的字节数,而不是数据包大小。 可用于读取的数据的量可从一个或多个TCP 来构造。 在OSI模型中 ,一个TCP (第4层:传输)可以由一个或多个IP层分组 (第3层:网)构成,并且每个数据包可以从一个或多个以太网 (第2层:数据链路)被构造。

因此,我将承担应用程序有兴趣知道如何读取的字节数,而不是明知下级的细节,比如一个包的大小。 对于这个问题几个解决方案:

  • 查询多少数据经由可用的插座socket::available()则相应地分配的缓冲区。

     std::vector<char> data(socket_.available()); boost::asio::read(socket_, boost::asio::buffer(data)); 
  • 使用一类Boost.Asio的可以在内存中成长,如boost::asio::streambuf 。 一些操作,如boost::asio::read()接受streambuf对象作为自己的缓冲区,并根据需要为操作将分配内存。 然而,完成条件应提供; 否则,该操作将继续,直到缓冲区已满。

     boost::asio::streambuf data; boost::asio::read(socket_, data, boost::asio::transfer_at_least(socket_.available())); 
  • 正如伊戈尔R.建议中的注释合并长度作为通信协议的一部分。 检查Boost.Asio的例子为通信协议的例子。 专注于协议,不一定对Boost.Asio的API 。

    • 在固定长度的协议,一个恒定字节大小被用于指示消息边界,如在Boost.Asio的Porthopper例子。 如读者知道消息的大小,读者可以预先分配缓冲区。
    • 在可变长度的协议,如在所使用的Boost.Asio的所述一个聊天例如,消息通常被分为两个部分:一个标头和主体。 一种方法是具有AA固定大小标头,包含各种元信息,如主体的长度。 这允许应用程序读取的报头到固定大小的缓冲区,解压体长,分配缓冲区为体,然后读取体。

       // Read fixed header. std::vector<char> data(fixed_header_size); boost::asio::read(socket_, boost::asio::buffer(data)); protocol::header header(data); network_to_local(header); // Handle endianess. // Read body. data.resize(header.body_length()); boost::asio::read(socket_, boost::asio::buffer(data)); protocol::body body(data); network_to_local(body); // Handle endianess. 

在另一方面,如果我错了,和你需要的总长度的数据包,那么可以使用basic_raw_socket 。 Boost.Asio的的ICMP例子演示了如何从一个socket读取IPv4数据包,并提取头的字段值。



文章来源: C++ Boost asio get data size?