boost asio transfer_exactly读取0个字节

时间:2017-08-01 06:36:43

标签: c++ c++11 networking boost boost-asio

给定一个通过tcp传输文件内容的示例服务器 -

#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 个答案:

答案 0 :(得分:2)

根据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_);

解决问题。