我使用升壓ASIO圖書館閱讀使用TCP的一些數據。在使用a.accept(*sock);
後,如何獲取客戶端發送的第一個數據包的大小?C++ Boost asio獲取數據大小?
我使用(sock->remote_endpoint().address()).to_string()
來獲取用戶的IP地址,所以我想必須有一個類似的簡單方法來獲取包的大小,對吧?
我使用升壓ASIO圖書館閱讀使用TCP的一些數據。在使用a.accept(*sock);
後,如何獲取客戶端發送的第一個數據包的大小?C++ Boost asio獲取數據大小?
我使用(sock->remote_endpoint().address()).to_string()
來獲取用戶的IP地址,所以我想必須有一個類似的簡單方法來獲取包的大小,對吧?
在應用程序級別,知道當前可用於讀取的字節數通常更有用,而不是數據包大小。可用於讀取的數據的量可從一個或多個TCP 段來構造。在OSI model,一個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 examples。專注於協議,不一定在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.
在另一方面,如果我錯了,和你需要一個包的total length,那麼可以使用basic_raw_socket
。 Boost.Asio的的ICMP example演示了從套接字讀取IPv4數據包,並提取頭的字段值。
知道收到的數據包大小的唯一方法是使用某個協議(定義消息數據中的結構和大小),或者在消息有效負載數據前發送大小。 –
確實TCP支持告訴數據包大小?另外,我想在調用'boost :: thread t(session,sock)之前獲取數據包大小;' – Luka
不,TCP是一種透明的傳輸機制。 –