C ++ boost asio get data size?

I am using boost asio library to read some data using tcp. After using a.accept(*sock); How to get the size of the 1st packet that the client will send?

I use (sock->remote_endpoint().address()).to_string() to get the user's IP address, so I think there should be the same easy way to get the packet size, right?

+1
source share
1 answer

At the application level, it is often much more useful to know the number of bytes currently available for reading, rather than the size of the packet. The amount of data available for reading can be built from one or more TCP segments. In the OSI model, a TCP segment (layer 4: transport) can be constructed from one or more IP layer packets (layer 3: network), and each packet can be built from one or more Ethernet frames (Layer 2: Data Link).

Therefore, I am going to assume that the application is interested in knowing how many bytes to read, and not knowing lower-level details such as packet size. There are several solutions to this problem:

  • Request a socket about how much data is available through socket::available() , then apportion the buffer accordingly.

     std::vector<char> data(socket_.available()); boost::asio::read(socket_, boost::asio::buffer(data)); 
  • Use a class that Boost.Asio can grow in memory, like boost::asio::streambuf . Some operations, such as boost::asio::read() take streambuf objects as their buffer and allocate the memory needed for the operation. However, a termination condition must be provided; otherwise, the operation will continue until the buffer is full.

     boost::asio::streambuf data; boost::asio::read(socket_, data, boost::asio::transfer_at_least(socket_.available())); 
  • As Igor R. suggests in the comments, include length as part of the communication protocol. For example communication protocols, check Boost.Asio examples . Focus on the protocol, not necessarily the Boost.Asio API .

    • A fixed-length protocol uses a constant byte size to indicate message boundaries, for example, in the Boost.Asio Porthopper example. Since the reader knows the size of the message, the reader can preallocate a buffer.
    • In a variable-length protocol, for example, used in the Boost.Asio Chat example, the message is often divided into two parts: the header and the body. One approach is to have a fixed-size header that contains various meta-information, such as body length. This allows the application to read the header into a fixed-size buffer, extract the length of the body, allocate a buffer for the body, and then read the body.

       // 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. 

On the other hand, if I am mistaken and you need the total length of the packet, then basic_raw_socket can be used. Boost.Asio The ICMP example demonstrates reading IPv4 packets from a socket and retrieving header field values.

+3
source

Source: https://habr.com/ru/post/1213252/


All Articles