Boost asio: Is it possible to include the accepted tcp socket in basic_socket_iostream (or somehow get it from it)?

So here is my problem: we already have an accepted boost asio tcp socket. And all of our APIs use it. And we just need to do this โ€œread timeoutโ€ in one function.

Here you can make such a "read wait time", as shown here . But I get the asio tcp socket extension from my APIs, so I wonder if it was possible to turn Boost :: asio socket into basic_socket_iostream , How do I do this?

+6
source share
3 answers

I wonder how it is possible to turn Boost :: asio socket into basic_socket_iostream. How to do it?

you can use tcp::iostream::rdbuf() to get a pointer to socket::basic_socket_streambuf , then assign() descriptor.

 #include <boost/asio.hpp> int main() { boost::asio::io_service io_service; boost::asio::ip::tcp::socket socket( io_service ); boost::asio::ip::tcp::iostream stream; stream.rdbuf()->assign( boost::asio::ip::tcp::v4(), socket.native_handle() ); } 

Although it is very minimized, and I highly recommend not to go along this route. As pointed out by Ralf's answer , and my answer to your related question, you really should use deadline_timer for this.

+4
source

You do not indicate whether there is a requirement not to use asynchronous APIs, so maybe this will help you and maybe not:

If I do not understand you, I think SO answer that you are referring to another use case, i.e. timeout using tcp :: iostream. If you just want to add a timeout to reading, have you looked at timeouts in the asio documentation ? This is the standard approach to timeout a socket operation.

+2
source

For anyone who runs into this problem, after I try to do this for hours, I decided to write a simple wrapper class using Boost "Devices": http://www.boost.org/doc/libs/1_64_0 /libs/iostreams/doc/tutorial/container_source.html

 #include <iostream> #include <boost/smart_ptr.hpp> #include <boost/asio.hpp> #include <boost/iostreams/stream.hpp> #include <boost/iostreams/concepts.hpp> using boost::asio::ip::tcp; typedef boost::shared_ptr<tcp::socket> socket_ptr; class my_source : public boost::iostreams::source { public: my_source(socket_ptr sock) : _sock(sock) { } std::streamsize read(char* s, std::streamsize n) { return _sock->read_some(boost::asio::buffer(s, n)); } private: socket_ptr _sock; }; 
Usage example

:

 boost::iostreams::stream<my_source> in(sock); for (;;) { std::getline(in, line); if (line.length() > 0) std::cout << line << std::endl; else break; } 
+1
source

Source: https://habr.com/ru/post/900744/


All Articles