我现在用的升压ASIO图书馆阅读使用TCP的一些数据。 使用后a.accept(*sock);
,如何让第一分组中的客户端发送的大小?
我使用(sock->remote_endpoint().address()).to_string()
来获得用户的IP地址,所以我想必须有一个类似的简单方式来获得数据包的大小,对不对?
我现在用的升压ASIO图书馆阅读使用TCP的一些数据。 使用后a.accept(*sock);
,如何让第一分组中的客户端发送的大小?
我使用(sock->remote_endpoint().address()).to_string()
来获得用户的IP地址,所以我想必须有一个类似的简单方式来获得数据包的大小,对不对?
在应用层面,它往往是更为有用知道目前可供读取的字节数,而不是数据包大小。 可用于读取的数据的量可从一个或多个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的所述一个聊天例如,消息通常被分为两个部分:一个标头和主体。 一种方法是具有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数据包,并提取头的字段值。