[英]C++ Boost asio get data size?
我正在使用boost 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()));
正如Igor R.在評論中所建議的,將長度作為通信協議的一部分。 查看Boost.Asio 示例以獲取通信協議示例。 關注協議,不必關注Boost.Asio API 。
在可變長度協議中,例如在Boost.Asio Chat示例中使用的協議,消息通常分為兩部分:標頭和正文。 一種方法是具有一個固定大小的標頭,其中包含各種元信息,例如主體的長度。 這允許應用程序將標頭讀取到固定大小的緩沖區中,提取主體長度,為主體分配一個緩沖區,然后讀取主體。
// 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示例演示了如何從套接字讀取IPv4數據包,並提取標頭的字段值。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.