2011-02-08 15 views
6

クライアントから圧縮された文字列(zlibで圧縮された)を受け取るサーバーがあり、この文字列を受け取るためにboost::asioライブラリのasync_receiveを使用していましたが、すべてのバイトが受信されるという保証はないので、今度はそれをasync_readに変更する必要があります。私が直面している問題は、受信したバイトのサイズが可変であるため、受信するバイト数を知らずにasync_readを使用する方法がわかりません。 async_receiveではちょうどboost::array<char, 1024>がありますが、これは必ずしも完全には満たされていないバッファです。boost :: asio async_read保証すべてのバイトが読み取られる

誰もが、私は事前に受信するバイト数を知らないにもかかわらずasync_read使用できるソリューションを提案できる場合、私は疑問に思いましたか?

void tcp_connection::start(boost::shared_ptr<ResolverQueueHandler> queue_handler) 
{ 
    if (!_queue_handler.get()) 
     _queue_handler = queue_handler; 

    std::fill(buff.begin(), buff.end(), 0); 

    //socket_.async_receive(boost::asio::buffer(buff), boost::bind(&tcp_connection::handle_read, shared_from_this(), boost::asio::placeholders::error)); 
    boost::asio::async_read(socket_, boost::asio::buffer(buff), boost::bind(&tcp_connection::handle_read, shared_from_this(), boost::asio::placeholders::error)); 
} 

buffboost::array<char, 1024>

答えて

19

どのように他の方法でこれを行う予定ですか?あなたが含まれているボディが続くと予想メッセージの長さを定義するヘッダを持っていることを意味 - メッセージによって

  1. は非同期マナーに変数のサイズのデータ​​を送信するにはいくつかの一般的な方法があります。指定された長さのデータ。

  2. ストリーミング - 完全なパケットを取得した時点を知るためのマーカーがいくつかあります(これは非常に広い)。
  3. 接続ごとに、データの各完全パケットが単一の接続で送信され、データが一度完了すると閉じます。

だから、単一のIPパケットは〜1500バイトのMTUサイズに制限され、それでもあなたはギガバイトの大容量ファイルをダウンロードすることができ、あなたのデータを解析することができ、またはなどを送られた長さ...

+4

+1可能な解決策の素敵な要約 –

2

使用async_read_untilで、独自のmatch conditionを作成したり、圧縮された文字列に期待するバイト数を含むヘッダを送信するためにあなたのプロトコルを変更します。

0

お気に入りのウェブサイトからダウンロードし、YouTubeでメガバイトサイズの動画を見ることができます。

あなたは、生データの実際のサイズを示すヘッダを送信した後、あなたはすべてのバイトを受信完了するまで小さな塊の部分でデータを受信する必要があります。 Content-Length::あなたはHTTP経由で大きなファイルをダウンロードするとき例えば

は、ファイルのサイズを示すヘッダのフィールドがあります。

関連する問題