Boost ASIO socket reads N bytes no more no less and wait until they come or a timeout exception?

Creating a simple TCP server based on examples , but it still does not work out how to create a socket that will read a certain number of bytes, and if it will not be enough to wait. I need this to be a non-asynchronous operation.

#include <iostream> #include <boost/asio.hpp> #ifdef _WIN32 #include "Windows.h" #endif using namespace boost::asio::ip; using namespace std; int main(){ int m_nPort = 12345; boost::asio::io_service io_service; tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), m_nPort)); cout << "Waiting for connection..." << endl; tcp::socket socket(io_service); acceptor.accept(socket); cout << "connection accepted" << endl; try { socket.send(boost::asio::buffer("Start sending me data\r\n")); } catch(exception &e) { cerr << e.what() << endl; //"The parameter is incorrect" exception } } 

How to get 10,000 bytes and do it either until all 10,000 have arrived or 1000 millisecond timeouts and make an exception?

+6
source share
2 answers

Boost 1.47.0 has just implemented a timeout function for basic_socket_iostream , namely the expires_at and expires_from_now .

Here is an example based on your snippet:

 #include <iostream> #include <boost/asio.hpp> using namespace boost::asio::ip; using namespace std; int main(){ int m_nPort = 12345; boost::asio::io_service io_service; tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), m_nPort)); cout << "Waiting for connection..." << endl; tcp::iostream stream; acceptor.accept(*stream.rdbuf()); cout << "Connection accepted" << endl; try { stream << "Start sending me data\r\n"; // Set timeout in 5 seconds from now stream.expires_from_now(boost::posix_time::seconds(5)); // Try to read 12 bytes before timeout char buffer[12]; stream.read(buffer, 12); // Print buffer if fully received if (stream) // false if read timed out or other error { cout.write(buffer, 12); cout << endl; } } catch(exception &e) { cerr << e.what() << endl; } } 

This program works for me on Linux.

Please note that I am not a supporter of the fact that you use timeouts instead of an asynchronous operation with a timer timer. It is up to you. I just wanted to show that timeouts are possible with basic_socket_iostream .

+6
source

How to disable timeout and throw an exception?

Generally speaking, you only get timeouts and cancellations when using asynchronous methods. There are some platform-specific ways to do this that were discussed on SO in previous questions . I highly recommend that you research using asynchronous methods, this will greatly facilitate understanding of logic.

However, you can present a synchronous interface using the asynchronous methods below it. This is done by blocking the TCP client timeout example provided by the Asio library. Beware, however, that the example is not entirely simple (although well-commented) because of its inverse of control and the use of lambda functions. I suggest you research using asynchronous methods just before trying something like this.

How to get 10000 bytes?

use async_read free function, comments section describes exactly what you need

Notes

This overload is equivalent to calling:

 boost::asio::async_read( s, buffers, boost::asio::transfer_all(), handler); 

where your buffer size is 10,000 bytes.

0
source

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


All Articles