@john-lee
2021-01-03T09:15:53.000000Z
字数 1918
阅读 626
Boost.Asio
通过实现协议类型要求,可以添加对其它套接字协议(如蓝牙或 IRCOMM 套接字)的支持。然而,在许多情况下,这些协议也可以与 Boost.Asio 的通用协议支持。为此,Boost.Asio 提供了以下四个类:
generic::datagram_protocol
generic::raw_protocol
generic::seq_packet_protocol
generic::stream_protocol
这些类实现了协议类型要求,但允许用户在运行时指定地址族(如AF_INET
)和协议类型(如IPPROTO_TCP
)。例如:
boost::asio::generic::stream_protocol::socket my_socket(my_io_context);
my_socket.open(boost::asio::generic::stream_protocol(AF_INET, IPPROTO_TCP));
...
端点类模板boost::asio::generic::basic_endpoint
,用于支持这些协议类。如果此端点的本机表示适合sockaddr_storage
对象,则该端点可以容纳任何其它端点类型。此类还将从实现端点类型要求的其它类型转换:
boost::asio::ip::tcp::endpoint my_endpoint1 = ...;
boost::asio::generic::stream_protocol::endpoint my_endpoint2(my_endpoint1);
转换是隐式的,以便支持以下用例:
boost::asio::generic::stream_protocol::socket my_socket(my_io_context);
boost::asio::ip::tcp::endpoint my_endpoint = ...;
my_socket.connect(my_endpoint);
当使用C++ 11时,可以从套接字(或接受器)对象执行移动构造,以转换为更一般的协议的套接字(或接受器)类型。如果协议转换有效:
Protocol1 p1 = ...;
Protocol2 p2(p1);
然后允许相应的套接字转换:
Protocol1::socket my_socket1(my_io_context);
...
Protocol2::socket my_socket2(std::move(my_socket1));
例如,一种可能的转换是从 TCP 套接字转换为通用的面向流的套接字:
boost::asio::ip::tcp::socket my_socket1(my_io_context);
...
boost::asio::generic::stream_protocol::socket my_socket2(std::move(my_socket1));
这些转换也可用于移动分配。
这些转换不限于上述通用协议类。用户定义的协议可以通过类似地确保从Protocol1
到Protocol2
的转换是有效的来利用这个特性,如上所述。
为了方便起见,只要相应的协议转换有效,套接字接受者的accept()
和async_accept()
函数就可以直接接受为不同协议的套接字类型。例如,支持以下内容,因为协议boost::asio::ip::tcp
可转换为boost::asio::generic::stream_protocol
:
boost::asio::ip::tcp::acceptor my_acceptor(my_io_context);
...
boost::asio::generic::stream_protocol::socket my_socket(my_io_context);
my_acceptor.accept(my_socket);
generic::datagram_protocol,generic::raw_protocol,generic::seq_packet_protocol,generic::stream_protocol,协议类型要求。
Copyright © 2003-2020 Christopher M. Kohlhoff
Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)