2017-08-01 70 views
4

鑑於其通過TCP傳送文件的內容的示例服務器 -升壓ASIO transfer_exactly讀取0字節

#include <vector> 
#include <fstream> 
#include <iostream> 
#include <boost/asio.hpp> 

using namespace boost::asio; 
using namespace boost::system; 
using namespace boost::asio::ip; 

using std::cerr; 
using std::endl; 
using std::ifstream; 
using std::vector; 
using std::ios; 
using stream_iter = std::istreambuf_iterator<char>; 

int main() 
{ 
    ifstream input("movie.ogv", ios::in | ios::binary); 
    vector<uint8_t> stream((stream_iter(input)), stream_iter()); 

    io_service ioservice; 
    tcp::acceptor acceptor(ioservice, tcp::endpoint(tcp::v4(), 8000)); 
    tcp::socket socket(ioservice); 
    acceptor.accept(socket); 

    error_code ec; 
    write(socket, boost::asio::buffer(stream), ec); 
    if (ec) { 
     cerr << ec.message() << endl; 
    } 
} 

我寫以下客戶端提取開始文件的報頭被傳送 -

#include <vector> 
#include <iostream> 
#include <array> 
#include <boost/asio.hpp> 

using namespace boost::asio; 
using namespace boost::system; 
using namespace boost::asio::ip; 

using std::cerr; 
using std::endl; 
using std::ifstream; 
using std::vector; 
using std::ios; 
using stream_iter = std::istreambuf_iterator<char>; 

int main() 
{ 
    int header_size_ = 30000; 
    error_code ec; 
    vector<char> headerBytesBuf; 
    headerBytesBuf.reserve(header_size_); 
    io_service ioservice; 
    tcp::socket socket(ioservice); 
    socket.connect(tcp::endpoint(tcp::v4(), 8000)); 
    const auto bTransfer = read(socket, buffer(headerBytesBuf), 
           transfer_exactly(header_size_), ec); 

    if (ec) { 
     socket.close(); 
     std::cerr << ec.message(); 
    } 

    std::cout << headerBytesBuf.size(); 
} 

相關的代碼是 - const auto bTransfer = read(socket, buffer(headerBytesBuf), transfer_exactly(header_size_), ec);,它將0字節讀入向量中,但未記錄錯誤:/

將該行更改爲 -

std::array<char, 128> buf; 
size_t total_transfer = 0; 

while(total_transfer < header_size_) { 
    size_t len = socket.read_some(boost::asio::buffer(buf)); 
    total_transfer += len; 
    if (len <= 0) break; 
} 

total_transfer報告30800,我現在可以修剪和內環路追加到我的vector。但爲什麼不是第一種在這裏工作的方法?

+1

不是100%確定,但我認爲你想改變'headerBytesBuf.reserve(header_size _);'到'headerBytesBuf.resize(header_size _);',因爲ASIO緩衝區在初始化後對原始數據起作用,他們沒有辦法調整大小矢量。您正在有效地傳遞一個0大小的緩衝區,它會立即觸發'所提供的緩衝區已滿。 – Frank

回答

3

boost::asio::read()文檔:http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/read/overload3.html

調用將阻塞,直到滿足下列條件之一爲真:

  • 所提供的緩衝器滿了。也就是說,傳輸的字節數等於緩衝區大小的總和。
  • 的completion_condition函數對象返回0。

你打的第一個條件,因爲你傳遞一個0大小的緩衝區。

所有你需要做的是改變

headerBytesBuf.reserve(header_size_); 

headerBytesBuf.resize(header_size_); 

來解決該問題。