2014-03-07 114 views
1

我使用升壓ASIO圖書館閱讀使用TCP的一些數據。在使用a.accept(*sock);後,如何獲取客戶端發送的第一個數據包的大小?C++ Boost asio獲取數據大小?

我使用(sock->remote_endpoint().address()).to_string()來獲取用戶的IP地址,所以我想必須有一個類似的簡單方法來獲取包的大小,對吧?

+0

知道收到的數據包大小的唯一方法是使用某個協議(定義消息數據中的結構和大小),或者在消息有效負載數據前發送大小。 –

+0

確實TCP支持告訴數據包大小?另外,我想在調用'boost :: thread t(session,sock)之前獲取數據包大小;' – Luka

+0

不,TCP是一種透明的傳輸機制。 –

回答

3

在應用程序級別,知道當前可用於讀取的字節數通常更有用,而不是數據包大小。可用於讀取的數據的量可從一個或多個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 Porthopper示例中。由於讀者知道消息的大小,讀者可以預先分配一個緩衝區。
    • 在可變長度協議,如在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數據包,並提取頭的字段值。

相關問題