Boost ASIO socket read N bytes not more not less and wait until they come or timeout exception?

坚强是说给别人听的谎言 提交于 2019-12-05 07:53:09

Boost 1.47.0 just introduced a timeout feature for basic_socket_iostream, namely, the expires_at and expires_from_now methods.

Here's 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'm not advocating that you use timeouts instead of asynchronous operation with a deadline timer. It's up to you to decide. I just wanted to show that timeouts are possible with basic_socket_iostream.

Sam Miller

How to timeout and throw an exception?

Generally speaking, you only get timeouts and cancelability when using asynchronous methods. There are some platform specific ways around this, which have been discussed on SO in previous questions. I strongly suggest you investigate using asynchronous methods, it will make understanding the logic much easier.

That said, you can present a synchronous interface by using asynchronous methods underneath. This is done in the blocking TCP client timeout example provided by the Asio library. Beware however, the example isn't entirely straightforward (albeit, well commented) due to its inversion of control and use of lambda functions. I suggest you investigate using asynchronous methods directly prior to attempting something like this.

How to receive 10000 bytes?

use the async_read free function, the remarks section describes exactly what you need

Remarks

This overload is equivalent to calling:

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

where your buffer is 10,000 bytes in size.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!