Boost C++ 库

...世界上最受推崇和专业设计的 C++ 库项目之一。 Herb SutterAndrei Alexandrescu, C++ Coding Standards

PrevUpHomeNext

basic_stream

一个流套接字包装器,具有超时、执行器和速率限制策略。

概要

定义于头文件 <boost/beast/core/basic_stream.hpp>

template<
    class Protocol,
    class Executor = net::any_io_executor,
    class RatePolicy = unlimited_rate_policy>
class basic_stream
类型

名称

描述

endpoint_type

端点类型。

executor_type

与流关联的执行器的类型。

protocol_type

协议类型。

rebind_executor

将流类型重新绑定到另一个执行器。

socket_type

底层套接字的类型。

成员函数

名称

描述

async_connect

异步地将流连接到指定的端点。

通过异步地尝试序列中的每个端点来建立连接。

async_read_some

异步地读取一些数据。

async_write_some

异步地写入一些数据。

basic_stream [构造函数]

构造函数。

移动构造函数。

cancel

取消与套接字关联的所有异步操作。

close

关闭定时流。

connect

将流连接到指定的端点。

通过尝试序列中的每个端点来建立连接。

expires_after

为后续的逻辑操作设置超时。

expires_at

为后续的逻辑操作设置超时。

expires_never

禁用后续逻辑操作的超时。

get_executor

获取与对象关联的执行器。

operator=

移动赋值(已删除)。

rate_policy

返回与对象关联的速率策略。

read_some

读取一些数据。

release_socket

释放底层套接字的所有权。

socket

返回对底层套接字的引用。

write_some

写入一些数据。

~basic_stream [析构函数]

析构函数。

描述

此流包装了一个 net::basic_stream_socket 以提供以下功能

尽管流支持多个并发的未完成异步操作,但流对象不是线程安全的。 调用者负责确保一次只有一个线程访问该流。 这包括网络实现访问流及其底层套接字的时间。 为了满足此线程安全要求,所有异步操作都必须由流在同一隐式 strand(只有一个线程 net::io_context::run)或同一显式 strand(例如 net::strand 的实例)中执行。

具有显式关联执行器的完成处理程序(例如那些因使用 net::bind_executor 而产生的)将由流使用关联的执行器调用。 否则,完成处理程序将由构造时与流关联的执行器调用。 与此流一起使用的执行器类型必须满足以下要求

执行器类型 net::strand 满足这些要求。 在流类模板中使用 strand 作为执行器提供了额外的符号便利:不需要在每个单独的启动函数调用中指定 strand。

与其他流包装器不同,底层套接字是通过 socket 成员函数而不是 next_layer 访问的。 这导致在调用 get_lowest_layer 时返回 basic_stream

用法

要使用此流,请声明该类的一个实例。 然后,在每个需要超时的逻辑操作之前,调用带有持续时间的 expires_after,或调用带有时间点的 expires_at。 或者,调用 expires_never 以禁用后续逻辑操作的超时。 逻辑操作是对超时流的异步读取、异步写入或异步连接函数的一个或多个直接或间接调用的一系列操作。

当设置超时并执行混合操作(例如,包括读取和写入的操作)时,超时将应用于封闭操作中使用的所有中间异步操作。 这允许将超时应用于未专门编写为允许超时的流算法,当这些算法被传递一个设置了超时的超时流时。

当发生超时时,套接字将被关闭,从而取消任何挂起的 I/O 操作。 这些已取消操作的完成处理程序将使用错误 beast::error::timeout 调用。

示例

此函数使用超时读取 HTTP 请求,然后使用不同的超时发送 HTTP 响应。

void process_http_1 (tcp_stream& stream, net::yield_context yield)
{
    flat_buffer buffer;
    http::request<http::empty_body> req;

    // Read the request, with a 15 second timeout
    stream.expires_after(std::chrono::seconds(15));
    http::async_read(stream, buffer, req, yield);

    // Calculate the response
    http::response<http::string_body> res = make_response(req);

    // Send the response, with a 30 second timeout.
    stream.expires_after (std::chrono::seconds(30));
    http::async_write (stream, res, yield);
}

上面的示例可以通过简单的修改使用单个超时来表达。 以下函数首先读取 HTTP 请求,然后发送 HTTP 响应,并使用单个超时,该超时适用于读取和写入的整个组合操作

void process_http_2 (tcp_stream& stream, net::yield_context yield)
{
    flat_buffer buffer;
    http::request<http::empty_body> req;

    // Require that the read and write combined take no longer than 30 seconds
    stream.expires_after(std::chrono::seconds(30));

    http::async_read(stream, buffer, req, yield);

    http::response<http::string_body> res = make_response(req);
    http::async_write (stream, res, yield);
}

一些流算法,例如 ssl::stream::async_handshake,执行读取和写入操作。 在调用此类复合流算法的启动函数之前设置的超时将应用于整个复合操作。 例如,可以像这样在执行 SSL 握手时设置超时

void do_ssl_handshake (net::ssl::stream<tcp_stream>& stream, net::yield_context yield)
{
    // Require that the SSL handshake take no longer than 10 seconds
    stream.expires_after(std::chrono::seconds(10));

    stream.async_handshake(net::ssl::stream_base::client, yield);
}
阻塞 I/O

同步函数的行为与包装的 net::basic_stream_socket 的行为相同。 执行阻塞调用时,超时不可用。

模板参数

类型

描述

协议

满足 Protocol 要求的类型,表示用于基本流套接字的协议。 常见的选择是 net::ip::tcp

执行器

满足 Executor 要求的类型,用于提交所有尚未关联执行器的完成处理程序。 如果省略此类型,则将使用默认值 net::any_io_executor

线程安全

不同对象:安全。

共享对象:不安全。 应用程序还必须确保所有异步操作都在同一隐式或显式 strand 中执行。

参见

PrevUpHomeNext