CARLA
 
载入中...
搜索中...
未找到
detail/Token.h
浏览该文件的文档.
1// Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma
2// de Barcelona (UAB).
3//
4// This work is licensed under the terms of the MIT license.
5// For a copy, see <https://opensource.org/licenses/MIT>.
6
7#pragma once
8/// \file
9/// 包含CARLA流处理相关头文件和Boost.Asio网络库头文件。
10#include "carla/Debug.h"/// 包含CARLA的调试功能相关定义。
11#include "carla/streaming/EndPoint.h"/// 包含CARLA流处理的端点(EndPoint)类定义。
12#include "carla/streaming/Token.h"/// 包含CARLA流处理的令牌(Token)类定义。
13#include "carla/streaming/detail/Types.h"/// 包含CARLA流处理细节部分的类型定义。
14
15#include <boost/asio/ip/address.hpp>/// 包含Boost.Asio库中的IP地址类定义。
16#include <boost/asio/ip/tcp.hpp>/// 包含Boost.Asio库中的TCP协议类定义。
17#include <boost/asio/ip/udp.hpp> /// 包含Boost.Asio库中的UDP协议类定义。
18/**
19 * @namespace carla::streaming::detail
20 * @brief CARLA流传输模块的详细实现命名空间。
21 */
22
23 /**
24 * @struct token_data
25 * @brief 令牌数据结构,用于存储流传输的相关信息。
26 * @ingroup carla::streaming::detail
27 *
28 * 此结构体用于存储流ID、端口号、协议类型和地址类型等流传输的基本信息。
29 * 使用#pragma pack(push, 1)确保结构体成员紧密排列,无填充字节。
30 */
31namespace carla {
32namespace streaming {
33namespace detail {
34
35#pragma pack(push, 1)
36
37 struct token_data {
38 /**
39 * @brief 流ID,用于唯一标识一个流。
40 */
42 /**
43 * @brief 端口号,用于网络通信。
44 */
45 uint16_t port = 0u;
46 /**
47 * @brief 协议类型枚举,指示使用的传输协议。
48 */
49 enum class protocol : uint8_t {
50 not_set,///< 未设置协议
51 tcp,///< TCP协议
52 udp ///< UDP协议
53 } protocol = protocol::not_set;
54 /**
55 * @brief 地址类型枚举,指示IP地址的版本。
56 */
57 enum class address : uint8_t {
58 not_set,///< 未设置地址
59 ip_v4,///< IPv4地址
60 ip_v6///< IPv6地址
62 /**
63 * @brief 联合体,用于存储IPv4或IPv6地址。
64 *
65 * 根据address_type的值,此联合体可以存储IPv4或IPv6地址的字节表示。
66 */
67 union {
68 boost::asio::ip::address_v4::bytes_type v4;///< IPv4地址的字节表示
69 boost::asio::ip::address_v6::bytes_type v6;///< IPv6地址的字节表示
71 };
72
73#pragma pack(pop)
74 /**
75 * @brief 静态断言,用于确保`token_data`结构体的大小与`Token::data`的大小相同。
76 *
77 * 此断言用于验证`token_data`结构体的大小是否符合预期,即不超过192字节,具体分配如下:
78 * - IPv6地址:128字节
79 * - 状态:16字节
80 * - 端口:16字节
81 * - 流ID:32字节
82 *
83 * 如果`token_data`的大小超过192字节,则编译时会报错。
84 */
85 static_assert(
86 sizeof(token_data) == sizeof(Token::data),
87 "Size shouldn't be more than"
88 " v6 address : 128"
89 " + state : 16"
90 " + port : 16"
91 " + stream id : 32"
92 " -----------------"
93 " 192");
94
95 /**
96 * @brief 序列化流端点类,包含客户端订阅流所需的所有必要信息。
97 */
98 class token_type {
99 private:
100 /**
101 * @brief 根据协议类型获取对应的协议枚举值。
102 *
103 * @tparam P 协议类型,必须是`boost::asio::ip::tcp`或`boost::asio::ip::udp`。
104 * @return 如果P是`boost::asio::ip::tcp`,则返回`token_data::protocol::tcp`;如果是`boost::asio::ip::udp`,则返回`token_data::protocol::udp`。
105 * @throws 编译时断言,如果P不是有效的协议类型,则会导致编译错误。
106 */
107 template <typename P>
108 static constexpr auto get_protocol() {
109 static_assert(
110 std::is_same<P, boost::asio::ip::tcp>::value ||
111 std::is_same<P, boost::asio::ip::udp>::value, "Invalid protocol.");
112 return std::is_same<P, boost::asio::ip::tcp>::value ?
115 }
116 /**
117 * @brief 获取与令牌关联的端点。
118 *
119 * @tparam P 协议类型,必须是`boost::asio::ip::tcp`或`boost::asio::ip::udp`。
120 * @return 返回与令牌关联的端点。
121 * @throws 运行时断言,如果令牌无效或协议不匹配,则断言失败。
122 */
123 template <typename P>
124 boost::asio::ip::basic_endpoint<P> get_endpoint() const {
125 DEBUG_ASSERT(is_valid());// 假设is_valid()是一个检查令牌有效性的成员函数
126 DEBUG_ASSERT(get_protocol<P>() == _token.protocol);// 检查协议是否匹配
127 return {get_address(), _token.port};// 返回端点,包含地址和端口
128 }
129
130 public:
131 /**
132 * @brief 构造函数,根据给定的流ID和端点创建令牌。
133 *
134 * @tparam Protocol 端点使用的协议类型,必须是`boost::asio::ip::tcp`或`boost::asio::ip::udp`。
135 * @param stream_id 流ID,用于唯一标识一个流。
136 * @param ep 端点,包含地址和端口信息。
137 */
138 template <typename Protocol>
139 explicit token_type(
140 stream_id_type stream_id,
142 _token.stream_id = stream_id;
143 _token.port = ep.port();
144 _token.protocol = get_protocol<Protocol>();
145 set_address(ep.address());
146 }
147 /**
148 * @brief 构造一个token_type对象,使用指定的流ID和部分定义的端点。
149 *
150 * @param stream_id 流ID,用于唯一标识一个流。
151 * @param ep 部分定义的端点,包含端口和协议信息。
152 * @template Protocol 指定端点使用的协议类型,例如boost::asio::ip::tcp或boost::asio::ip::udp。
153 */
154 template <typename Protocol>
155 explicit token_type(
156 stream_id_type stream_id,
158 _token.stream_id = stream_id;
159 _token.port = ep.port();
160 _token.protocol = get_protocol<Protocol>();
161 }
162
163 /**
164 * @brief 默认构造函数,用于创建未初始化的token_type对象。
165 */
166 token_type() = default;
167 /**
168 * @brief 拷贝构造函数,用于创建与另一个token_type对象相同的副本。
169 */
170 token_type(const token_type &) = default;
171 /**
172 * @brief 转换构造函数,从Token对象创建token_type对象。
173 *
174 * @param rhs 要转换的Token对象。
175 */
176 token_type(const Token &rhs);
177 /**
178 * @brief 转换构造函数,从token_data对象创建token_type对象。
179 *
180 * @param data 要转换的token_data对象。
181 */
182 explicit token_type(token_data data) {
183 _token = data;
184 }
185 /**
186 * @brief 类型转换操作符,将token_type对象转换为Token对象。
187 *
188 * @return 转换后的Token对象。
189 */
190 operator Token() const;
191
192 /**
193 * @brief 获取流ID的引用。
194 *
195 * 返回流ID的引用,以便可以使用其地址作为缓冲区发送。
196 *
197 * @return 流ID的引用。
198 */
199 const auto &get_stream_id() const {
200 return _token.stream_id;
201 }
202 /**
203 * @brief 设置流ID。
204 *
205 * @param id 要设置的流ID。
206 */
208 _token.stream_id = id;
209 }
210 /**
211 * @brief 检查是否已设置地址。
212 *
213 * @return 如果已设置地址,则返回true;否则返回false。
214 */
215 bool has_address() const {
217 }
218 /**
219 * @brief 设置地址。
220 *
221 * @param addr 要设置的地址。
222 */
223 void set_address(const boost::asio::ip::address &addr);
224 /**
225 * @brief 获取地址。
226 *
227 * @return 当前设置的地址。
228 */
229 boost::asio::ip::address get_address() const;
230 /**
231 * @brief 获取端口号。
232 *
233 * @return 端口号。
234 */
235 auto get_port() const {
236 return _token.port;
237 }
238 /**
239 * @brief 检查令牌是否有效。
240 *
241 * 一个有效的令牌必须有一个设置的地址、协议类型和地址类型。
242 *
243 * @return 如果令牌有效,则返回true;否则返回false。
244 */
250 /**
251 * @brief 检查地址是否为IPv4。
252 *
253 * @return 如果地址是IPv4,则返回true;否则返回false。
254 */
255 bool address_is_v4() const {
257 }
258 /**
259 * @brief 检查地址是否为IPv6。
260 *
261 * @return 如果地址是IPv6,则返回true;否则返回false。
262 */
263 bool address_is_v6() const {
265 }
266 /**
267 * @brief 检查协议是否为UDP。
268 *
269 * @return 如果协议是UDP,则返回true;否则返回false。
270 */
271 bool protocol_is_udp() const {
273 }
274 /**
275 * @brief 检查协议是否为TCP。
276 *
277 * @return 如果协议是TCP,则返回true;否则返回false。
278 */
279 bool protocol_is_tcp() const {
281 }
282 /**
283 * @brief 检查是否具有相同的协议。
284 *
285 * 比较当前令牌的协议与给定端点的协议。
286 *
287 * @param endpoint 要比较的端点。
288 * @return 如果协议相同,则返回true;否则返回false。
289 */
290 template <typename Protocol>
291 bool has_same_protocol(const boost::asio::ip::basic_endpoint<Protocol> &) const {
292 return _token.protocol == get_protocol<Protocol>();
293 }
294 /**
295 * @brief 将令牌转换为UDP端点。
296 *
297 * 如果当前令牌的协议不是UDP,则行为未定义。
298 *
299 * @return UDP端点。
300 */
301 boost::asio::ip::udp::endpoint to_udp_endpoint() const {
302 return get_endpoint<boost::asio::ip::udp>();
303 }
304 /**
305 * @brief 将令牌转换为TCP端点。
306 *
307 * 如果当前令牌的协议不是TCP,则行为未定义。
308 *
309 * @return TCP端点。
310 */
311 boost::asio::ip::tcp::endpoint to_tcp_endpoint() const {
312 return get_endpoint<boost::asio::ip::tcp>();
313 }
314
315 private:
316 /**
317 * @brief 友元类,允许Dispatcher访问私有成员。
318 */
319 friend class Dispatcher;
320 /**
321 * @brief 存储令牌数据的成员变量。
322 */
324 };
325
326} // namespace detail
327} // namespace streaming
328} // namespace carla
#define DEBUG_ASSERT(predicate)
Definition Debug.h:68
包含与Carla流处理相关的底层细节的头文件。
std::array< unsigned char, 24u > data
Definition Token.h:20
Keeps the mapping between streams and sessions.
Definition Dispatcher.h:30
静态断言,用于确保token_data结构体的大小与Token::data的大小相同。
bool is_valid() const
检查令牌是否有效。
boost::asio::ip::tcp::endpoint to_tcp_endpoint() const
将令牌转换为TCP端点。
boost::asio::ip::address get_address() const
获取地址。
Definition Token.cpp:54
bool address_is_v6() const
检查地址是否为IPv6。
const auto & get_stream_id() const
获取流ID的引用。
static constexpr auto get_protocol()
根据协议类型获取对应的协议枚举值。
boost::asio::ip::basic_endpoint< P > get_endpoint() const
获取与令牌关联的端点。
token_type(stream_id_type stream_id, EndPoint< Protocol, PartiallyDefinedEndPoint > ep)
构造一个token_type对象,使用指定的流ID和部分定义的端点。
bool has_same_protocol(const boost::asio::ip::basic_endpoint< Protocol > &) const
检查是否具有相同的协议。
token_type()=default
默认构造函数,用于创建未初始化的token_type对象。
boost::asio::ip::udp::endpoint to_udp_endpoint() const
将令牌转换为UDP端点。
void set_address(const boost::asio::ip::address &addr)
设置地址。
Definition Token.cpp:19
auto get_port() const
获取端口号。
bool protocol_is_tcp() const
检查协议是否为TCP。
token_type(stream_id_type stream_id, const EndPoint< Protocol, FullyDefinedEndPoint > &ep)
构造函数,根据给定的流ID和端点创建令牌。
bool has_address() const
检查是否已设置地址。
token_data _token
存储令牌数据的成员变量。
bool protocol_is_udp() const
检查协议是否为UDP。
bool address_is_v4() const
检查地址是否为IPv4。
token_type(token_data data)
转换构造函数,从token_data对象创建token_type对象。
token_type(const token_type &)=default
拷贝构造函数,用于创建与另一个token_type对象相同的副本。
void set_stream_id(stream_id_type id)
设置流ID。
uint32_t stream_id_type
流ID的类型定义。
Definition Types.h:33
CARLA模拟器的主命名空间。
Definition Carla.cpp:139
uint16_t port
端口号,用于网络通信。
enum carla::streaming::detail::token_data::address address_type
boost::asio::ip::address_v4::bytes_type v4
IPv4地址的字节表示
stream_id_type stream_id
流ID,用于唯一标识一个流。
address
地址类型枚举,指示IP地址的版本。
protocol
协议类型枚举,指示使用的传输协议。
boost::asio::ip::address_v6::bytes_type v6
IPv6地址的字节表示
令牌数据结构,用于存储流传输的相关信息。 ::::