如何使用 async_read_until、async_write 和 Boost.Asio 编译此示例?

How to compile this example with async_read_until, async_write and Boost.Asio?

写了简短的例子:简单的回显程序。请帮助编译这个,因为我不明白为什么编译器错误

我试过这个:g++ -Wall -Wextra -pedantic client.cpp -o client -lboost_thread -lboost_system,但遇到下一个错误 https://pastebin.com/byevYxPa

#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <string>

using namespace boost::asio;
using error_code = boost::system::error_code;

io_service ioservice;
posix::stream_descriptor out(ioservice, STDOUT_FILENO);
posix::stream_descriptor  in(ioservice,  STDIN_FILENO);

std::string line;

void on_read(const error_code & err, std::size_t bytes);
void on_write(const error_code & err, std::size_t bytes);

void on_read(const error_code & err, std::size_t bytes) {
    if (err || line == "exit") return;
    line += "\n";
    async_write(out, buffer(line), on_write);
}

void on_write(const error_code & err, std::size_t bytes) {
    write(out, buffer("$ "));
    async_read_until(in, buffer(line),'\n',on_read);
}

int main() {
    async_read_until(in, buffer(line),'\n',on_read);
    ioservice.run();
}

我希望这段代码能正常工作并编译

client.cpp: In function ‘void on_read(const error_code&, std::size_t)’:
client.cpp:17:50: warning: unused parameter ‘bytes’ [-Wunused-parameter]
 void on_read(const error_code & err, std::size_t bytes) {
                                                  ^~~~~
client.cpp: In function ‘void on_write(const error_code&, std::size_t)’:
client.cpp:25:51: error: no matching function for call to ‘async_read_until(boost::asio::posix::stream_descriptor&, boost::asio::const_buffers_1, char, void (&)(const error_code&, std::size_t))’
     async_read_until(in, buffer(line),'\n',on_read);
                                                   ^
In file included from /usr/include/boost/asio/read_until.hpp:921:0,
                 from /usr/include/boost/asio.hpp:91,
                 from client.cpp:1:
/usr/include/boost/asio/impl/read_until.hpp:498:1: note: candidate: template<class AsyncReadStream, class Allocator, class ReadHandler> typename boost::asio::async_result<typename boost::asio::handler_type<WriteHandler, void(boost::system::error_code, long unsigned int)>::type>::type boost::asio::async_read_until(AsyncReadStream&, boost::asio::basic_streambuf<Allocator>&, char, ReadHandler&&)
 async_read_until(AsyncReadStream& s,
 ^~~~~~~~~~~~~~~~
/usr/include/boost/asio/impl/read_until.hpp:498:1: note:   template argument deduction/substitution failed:
client.cpp:25:51: note:   ‘boost::asio::const_buffers_1’ is not derived from ‘boost::asio::basic_streambuf<Allocator>’
     async_read_until(in, buffer(line),'\n',on_read);
                                                   ^
In file included from /usr/include/boost/asio/read_until.hpp:921:0,
                 from /usr/include/boost/asio.hpp:91,
                 from client.cpp:1:
/usr/include/boost/asio/impl/read_until.hpp:701:1: note: candidate: template<class AsyncReadStream, class Allocator, class ReadHandler> typename boost::asio::async_result<typename boost::asio::handler_type<WriteHandler, void(boost::system::error_code, long unsigned int)>::type>::type boost::asio::async_read_until(AsyncReadStream&, boost::asio::basic_streambuf<Allocator>&, const string&, ReadHandler&&)
 async_read_until(AsyncReadStream& s,
 ^~~~~~~~~~~~~~~~
/usr/include/boost/asio/impl/read_until.hpp:701:1: note:   template argument deduction/substitution failed:
client.cpp:25:51: note:   ‘boost::asio::const_buffers_1’ is not derived from ‘boost::asio::basic_streambuf<Allocator>’
     async_read_until(in, buffer(line),'\n',on_read);
                                                   ^
In file included from /usr/include/boost/asio/read_until.hpp:921:0,
                 from /usr/include/boost/asio.hpp:91,
                 from client.cpp:1:
/usr/include/boost/asio/impl/read_until.hpp:913:1: note: candidate: template<class AsyncReadStream, class Allocator, class ReadHandler> typename boost::asio::async_result<typename boost::asio::handler_type<WriteHandler, void(boost::system::error_code, long unsigned int)>::type>::type boost::asio::async_read_until(AsyncReadStream&, boost::asio::basic_streambuf<Allocator>&, const regex&, ReadHandler&&)
 async_read_until(AsyncReadStream& s,
 ^~~~~~~~~~~~~~~~
/usr/include/boost/asio/impl/read_until.hpp:913:1: note:   template argument deduction/substitution failed:
client.cpp:25:51: note:   ‘boost::asio::const_buffers_1’ is not derived from ‘boost::asio::basic_streambuf<Allocator>’
     async_read_until(in, buffer(line),'\n',on_read);
                                                   ^
In file included from /usr/include/boost/asio/read_until.hpp:921:0,
                 from /usr/include/boost/asio.hpp:91,
                 from client.cpp:1:
/usr/include/boost/asio/impl/read_until.hpp:1122:1: note: candidate: template<class AsyncReadStream, class Allocator, class MatchCondition, class ReadHandler> typename boost::asio::async_result<typename boost::asio::handler_type<WriteHandler, void(boost::system::error_code, long unsigned int)>::type>::type boost::asio::async_read_until(AsyncReadStream&, boost::asio::basic_streambuf<Allocator>&, MatchCondition, ReadHandler&&, typename std::enable_if<boost::asio::is_match_condition<MatchCondition>::value>::type*)
 async_read_until(AsyncReadStream& s,
 ^~~~~~~~~~~~~~~~
/usr/include/boost/asio/impl/read_until.hpp:1122:1: note:   template argument deduction/substitution failed:
client.cpp:25:51: note:   ‘boost::asio::const_buffers_1’ is not derived from ‘boost::asio::basic_streambuf<Allocator>’
     async_read_until(in, buffer(line),'\n',on_read);
                                                   ^
client.cpp:23:34: warning: unused parameter ‘err’ [-Wunused-parameter]
 void on_write(const error_code & err, std::size_t bytes) {
                                  ^~~
client.cpp:23:51: warning: unused parameter ‘bytes’ [-Wunused-parameter]
 void on_write(const error_code & err, std::size_t bytes) {
                                                   ^~~~~
client.cpp: In function ‘int main()’:
client.cpp:29:51: error: no matching function for call to ‘async_read_until(boost::asio::posix::stream_descriptor&, boost::asio::const_buffers_1, char, void (&)(const error_code&, std::size_t))’
     async_read_until(in, buffer(line),'\n',on_read);
                                                   ^
In file included from /usr/include/boost/asio/read_until.hpp:921:0,
                 from /usr/include/boost/asio.hpp:91,
                 from client.cpp:1:
/usr/include/boost/asio/impl/read_until.hpp:498:1: note: candidate: template<class AsyncReadStream, class Allocator, class ReadHandler> typename boost::asio::async_result<typename boost::asio::handler_type<WriteHandler, void(boost::system::error_code, long unsigned int)>::type>::type boost::asio::async_read_until(AsyncReadStream&, boost::asio::basic_streambuf<Allocator>&, char, ReadHandler&&)
 async_read_until(AsyncReadStream& s,
 ^~~~~~~~~~~~~~~~
/usr/include/boost/asio/impl/read_until.hpp:498:1: note:   template argument deduction/substitution failed:
client.cpp:29:51: note:   ‘boost::asio::const_buffers_1’ is not derived from ‘boost::asio::basic_streambuf<Allocator>’
     async_read_until(in, buffer(line),'\n',on_read);
                                                   ^
In file included from /usr/include/boost/asio/read_until.hpp:921:0,
                 from /usr/include/boost/asio.hpp:91,
                 from client.cpp:1:
/usr/include/boost/asio/impl/read_until.hpp:701:1: note: candidate: template<class AsyncReadStream, class Allocator, class ReadHandler> typename boost::asio::async_result<typename boost::asio::handler_type<WriteHandler, void(boost::system::error_code, long unsigned int)>::type>::type boost::asio::async_read_until(AsyncReadStream&, boost::asio::basic_streambuf<Allocator>&, const string&, ReadHandler&&)
 async_read_until(AsyncReadStream& s,
 ^~~~~~~~~~~~~~~~
/usr/include/boost/asio/impl/read_until.hpp:701:1: note:   template argument deduction/substitution failed:
client.cpp:29:51: note:   ‘boost::asio::const_buffers_1’ is not derived from ‘boost::asio::basic_streambuf<Allocator>’
     async_read_until(in, buffer(line),'\n',on_read);
                                                   ^
In file included from /usr/include/boost/asio/read_until.hpp:921:0,
                 from /usr/include/boost/asio.hpp:91,
                 from client.cpp:1:
/usr/include/boost/asio/impl/read_until.hpp:913:1: note: candidate: template<class AsyncReadStream, class Allocator, class ReadHandler> typename boost::asio::async_result<typename boost::asio::handler_type<WriteHandler, void(boost::system::error_code, long unsigned int)>::type>::type boost::asio::async_read_until(AsyncReadStream&, boost::asio::basic_streambuf<Allocator>&, const regex&, ReadHandler&&)
 async_read_until(AsyncReadStream& s,
 ^~~~~~~~~~~~~~~~
/usr/include/boost/asio/impl/read_until.hpp:913:1: note:   template argument deduction/substitution failed:
client.cpp:29:51: note:   ‘boost::asio::const_buffers_1’ is not derived from ‘boost::asio::basic_streambuf<Allocator>’
     async_read_until(in, buffer(line),'\n',on_read);
                                                   ^
In file included from /usr/include/boost/asio/read_until.hpp:921:0,
                 from /usr/include/boost/asio.hpp:91,
                 from client.cpp:1:
/usr/include/boost/asio/impl/read_until.hpp:1122:1: note: candidate: template<class AsyncReadStream, class Allocator, class MatchCondition, class ReadHandler> typename boost::asio::async_result<typename boost::asio::handler_type<WriteHandler, void(boost::system::error_code, long unsigned int)>::type>::type boost::asio::async_read_until(AsyncReadStream&, boost::asio::basic_streambuf<Allocator>&, MatchCondition, ReadHandler&&, typename std::enable_if<boost::asio::is_match_condition<MatchCondition>::value>::type*)
 async_read_until(AsyncReadStream& s,
 ^~~~~~~~~~~~~~~~
/usr/include/boost/asio/impl/read_until.hpp:1122:1: note:   template argument deduction/substitution failed:
client.cpp:29:51: note:   ‘boost::asio::const_buffers_1’ is not derived from ‘boost::asio::basic_streambuf<Allocator>’
     async_read_until(in, buffer(line),'\n',on_read);
                                                   ^

asio::buffer returns 可变缓冲区类型,它与 async_read_until 的第二个参数不匹配。此重载采用动态缓冲区,只需使用 boost::asio::dynamic_buffer.

void on_write(const error_code & err, std::size_t bytes) {
    write(out, buffer("$ "));
    async_read_until(in, dynamic_buffer(line),'\n',on_read);
}

int main() {
    async_read_until(in, dynamic_buffer(line),'\n',on_read);
    ioservice.run();
}

LIVE demo