使用boost的boost :: asio :: read直接写入cout

时间:2017-07-18 01:36:03

标签: c++ boost-asio

所以只是为了好玩,我想知道是否可以直接写入cout的缓冲区。

举个例子:

boost::asio::read(socket,boost::asio::buffer(<buffer of cout>); 来自“socket”的数据被读入缓冲流,它需要是cout的缓冲区。

是否可以在没有时间流对象的情况下写入cout?

2 个答案:

答案 0 :(得分:1)

直接,如零拷贝?只有操作系统支持它。

在某些符合POSIX标准的操作系统上,如果将输出重定向到实际文件,您可以使用sendfile系统调用实际对流进行零复制。

公平地说,它不会使用boost::asio::read(除非黑客过载调用::sendfile计数)。

您可能想要的是以最小的努力和最小的临时内存开销来复制流(例如,接收3GB流并不需要超过1k的内存)。

我建议boost::asio::ip::tcp::istream使用boost::iostreams::copy

最简单

这是一个没有boost::iostreams::copy的版本:

#include <boost/asio.hpp>
#include <iostream>
using boost::asio::ip::tcp;

int main() {
    tcp::iostream socket(tcp::endpoint {{}, 6767});
    std::cout << socket.rdbuf() << std::flush;
}

查看 Live On Coliru ,从netcat打印自己的源代码。

使用socket

如果必须使用现有的tcp::socket实例,您可以:

#include <boost/asio.hpp>
#include <iostream>
using boost::asio::ip::tcp;

int main() {
    boost::asio::io_service svc;
    tcp::socket s(svc);
    s.connect(tcp::endpoint {{}, 6767});

    tcp::iostream stream;
    stream.rdbuf()->assign(tcp::v4(), s.native_handle());

    std::cout << stream.rdbuf() << std::flush;
}

使用copy

<强> Live On Coliru

#include <boost/asio.hpp>
#include <boost/iostreams/copy.hpp>
#include <iostream>
using boost::asio::ip::tcp;

int main() {
    tcp::iostream socket(tcp::endpoint {{}, 6767});
    boost::iostreams::copy(socket, std::cout);
}

答案 1 :(得分:0)

ASIO streambuf的类是从stdlib streambuf派生的(子类型)。因此,以下代码必须执行您想要执行的操作:

const int to_read_bytes = 512;
boost::asio::streambuf my_buffer;
std::cout.rdbuf(&my_buffer);

// It will print into cout's buffer the read bytes
size_t n = boost::asio::read(socket, my_buffer.prepare(to_read_bytes));

// This is important as it moves the output characters to the input sequence
my_buffer.commit(n);

链接