2017-08-01 251 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_); 

来解决该问题。