c + +升压ASIO获取数据的大小? [英] C++ Boost asio get data size?

查看:152
本文介绍了c + +升压ASIO获取数据的大小?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用升压ASIO图书馆阅读使用TCP的一些数据。使用 a.accept(*袜子)后; ,如何获得第1包的大小的客户端将发送

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

我用。(sock-方式> remote_endpoint()地址())to_string()来获取用户的IP地址,所以我想一定有类似的简单的方式来获得数据包的大小,对吧?

I use (sock->remote_endpoint().address()).to_string() to get the IP address of the user, so I guess there must be a similar simple way to get the size of the packet, right?

推荐答案

目前应用层面,它往往是更加有用知道目前可供读取的字节数,而不是<青霉>包的尺寸。可用于读取数据的量可从一个或多个TCP的的构造。在 OSI模型,一个TCP的的(4层:传输)可以由一个或多个IP层的的构造(第3层:网络),并且每个包可以从一个被构造的或多个以太网的的(第2层:数据链路)。

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

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

Therefore, I am going to assume the application is interested in knowing how many bytes to read, rather than knowing lower level details, such as the size of a packet. There are a few solutions to this problem:


  • 查询有多少数据是通过<一个可用的插座href=\"http://www.boost.org/doc/libs/1_55_0/doc/html/boost_asio/reference/basic_stream_socket/available/overload1.html\"相对=nofollow> 插座::用() ,然后相应地分配缓冲区。

  • Query the socket for how much data is available via socket::available(), then allocate the buffer accordingly.

std::vector<char> data(socket_.available());
boost::asio::read(socket_, boost::asio::buffer(data));


  • 使用一个类,Boost.Asio的可以在内存中成长,如的 的boost ::支持ASIO ::流缓冲 。某些操作,如 的boost :: ASIO ::阅读() 接受流缓冲对象作为自己的缓冲区以及需要的将内存分配操作。然而,一个完成状态应提供;否则,操作将继续进行,直到缓冲区已满。

  • Use a class that Boost.Asio can grow in memory, such as boost::asio::streambuf. Some operations, such as boost::asio::read() accept streambuf objects as their buffer and will allocate memory as is required for the operation. However, a completion condition should 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()));
    


  • 作为<一个href=\"http://stackoverflow.com/questions/22255844/c-boost-asio-get-data-size#comment33850451_22255844\">Igor R.在评论表明,掺入长度作为通信协议的一部分。检查Boost.Asio的范例的例子通信协议。专注于协议,不一定对Boost.Asio的 API

  • As Igor R. suggests in the comments, incorporate length as part of the communication protocol. Check the Boost.Asio examples for examples of communication protocols. Focus on the protocol, not necessarily on the Boost.Asio API.


    • 在一个固定长度的协议,一个恒定字节大小被用于指示消息边界,如在Boost.Asio的<一href=\"http://www.boost.org/doc/libs/1_55_0/doc/html/boost_asio/examples/cpp03_examples.html#boost_asio.examples.cpp03_examples.porthopper\"相对=nofollow> Porthopper 例子。如读者知道该消息的大小,读者可以预先分配缓冲区。

    • 在可变长度协议,如在Boost.Asio的<使用的一个href=\"http://www.boost.org/doc/libs/1_55_0/doc/html/boost_asio/examples/cpp03_examples.html#boost_asio.examples.cpp03_examples.chat\"相对=nofollow>聊天例如,消息通常被分为两部分:一个首部和一个本体。一种方法是为具有一个固定的大小标头包含各种元信息,例如身体的长度。这允许应用程序读取一个头变成一个固定大小的缓冲区,提取体长,分配一个缓冲区为体,然后读取身上。

    • In a fixed length protocol, a constant byte size is used to indicate message boundaries, such as in the Boost.Asio Porthopper example. As the reader knows the size of the message, the reader can allocate a buffer in advance.
    • In a variable length protocol, such as the one used in the Boost.Asio Chat example, a message is often divided into two parts: a header and a body. One approach is to have a a fixed size header that contains various meta-information, such as the length of the body. This allows an application to read a header into a fixed size buffer, extract the body length, allocate a buffer for the body, 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.
    


  • 在另一方面,如果我错了,你确实需要总长度一包的,那么就可以使用 basic_raw_socket 。 Boost.Asio的的<一个href=\"http://www.boost.org/doc/libs/1_55_0/doc/html/boost_asio/examples/cpp03_examples.html#boost_asio.examples.cpp03_examples.icmp\"相对=nofollow> ICMP例如演示从套接字读取IPv4数据包,并提取头的字段值。

    On the other hand, if I am mistaken, and you do need the total length of a packet, then one can use the basic_raw_socket. Boost.Asio's ICMP example demonstrates reading IPv4 packets from a socket, and extracting the header's field values.

    这篇关于c + +升压ASIO获取数据的大小?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆