dar*_*enn 5 c++ boost boost-asio
我想从cin做异步读取因此我有一段代码
client.h
...
boost::asio::posix::stream_descriptor input;
boost::asio::streambuf input_buffer
Run Code Online (Sandbox Code Playgroud)
client.cpp
Client::Client(int argc, char **argv, boost::asio::io_service &io_service)
: tcp_socket(io_service)
, udp_socket(io_service)
, input(io_service, ::dup(STDIN_FILENO))
{
...
read_std_input();
}
void Client::read_std_input() {
async_read_until(input, input_buffer, '\n',
boost::bind(&Client::handle_std_read, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
Run Code Online (Sandbox Code Playgroud)
问题是:当我以正常方式[./client]运行我的客户端然后通过命令输入一些东西时,它就像魅力一样.但是,当我通过[./client <test]运行它时会抛出:
在抛出'boost :: exception_detail :: clone_impl的实例后终止调用
'what():assign:不允许操作中止
你知道问题可能是什么吗?谢谢!
Boost.Asio的POSIX面向流的描述符显然不支持常规文件.因此,如果test是一个普通文件,那么./client < test会导致posix::stream_descriptor::assign()尝试分配失败时STDIN_FILENO的stream_descriptor.该文件规定:
Boost.Asio包括添加的类,允许在POSIX文件描述符上执行同步和异步读写操作,例如管道,标准输入和输出以及各种设备(但不是常规文件).
考虑通过管道传递test文件的内容client.
$ cat test | ./client
Run Code Online (Sandbox Code Playgroud)
这是一个完整的示例程序和演示:
#include <iostream>
#include <boost/asio.hpp>
void handle_read(
const boost::system::error_code& error,
std::size_t bytes_transferred
)
{
std::cout << "read " << bytes_transferred << " bytes with "
<< error.message() << std::endl;
}
int main()
{
boost::asio::io_service io_service;
boost::asio::posix::stream_descriptor input(io_service);
// Assign STDIN_FILENO to the stream_descriptor. It will support
// pipes, standard input and output, and various devices, but NOT
// regular files.
boost::system::error_code error;
input.assign(STDIN_FILENO, error);
if (error)
{
std::cerr << error.message() << std::endl;
return -1;
}
boost::asio::streambuf input_buffer;
async_read_until(input, input_buffer, '\n', &handle_read);
io_service.run();
}
Run Code Online (Sandbox Code Playgroud)
示范
$ ./client testing standard inputenter read 23 bytes with Success $ echo "this is a test" > test $ ./client < test Operation not permitted $ cat test | ./client read 15 bytes with Success