dl
dl_net.h
浏览该文件的文档.
1
12#pragma once
13
14#include "io/dl_log.h"
15#include "base/dl_string.h"
16#include "system/dl_thread.h"
17#include "base/dl_list_mt.h"
18
19#include <magic_enum/magic_enum.hpp>
20
21namespace dl
22{
23
24constexpr uint8_t NETWORK_MESSAGE_TAG = 0x1e;
25constexpr bool NETWORK_LOG_CLIENT = true;
26constexpr bool NETWORK_LOG_SERVER = true;
27constexpr bool NETWORK_LOG_CLIENT_UDP = true;
28constexpr bool NETWORK_LOG_SERVER_UDP = true;
29
30#ifndef NDEBUG
31constexpr bool NETWORK_LOG_LOW = true; // 更底层的上下行日志(write、read完成后)
32#else
33constexpr bool NETWORK_LOG_LOW = false;
34#endif
35
36
38{
39
40};
41
43struct MsgHead
44{
45 uint32_t _id;
46 uint32_t _size;
47 uint32_t _check;
48 uint8_t _compress;
49 uint8_t _magic;
50 uint8_t _pad;
51};
52
54{
55 std::string _ip;
56 uint16_t _port;
58};
59
61{
64
65 template<IsEnum E>
66 E GetMsgId(uint32_t id)
67 {
68 auto msg_id_opt = magic_enum::enum_cast<E>(id);
69 if (!msg_id_opt.has_value())
70 {
71 log_info("未知协议id:{}", id);
72 return {};
73 }
74 return msg_id_opt.value();
75 }
76};
77
79{
83
84 template<IsEnum E>
85 E GetMsgId(uint32_t id)
86 {
87 auto msg_id_opt = magic_enum::enum_cast<E>(id);
88 if (!msg_id_opt.has_value())
89 {
90 log_info("未知协议id:{}", id);
91 return {};
92 }
93 return msg_id_opt.value();
94 }
95};
96
100
101class ClientImp;
104{
105public:
106 bool Connent(std::string_view ip, uint16_t port);
107
108 template<IsEnum E, IsPod T>
109 void Send(E msg_id, const T& a)
110 {
113 {
114 // 检测消息枚举
115 log_info(
116 "Send->[{}]:\n"
117 "消息id:{}\n"
118 "数据大小:{}\n"
119 "{}",
121 magic_enum::enum_name(msg_id),
122 buf.size(),
123 to_string_auto(buf));
124 }
125 Send((uint32_t)msg_id, buf);
126 }
127 template<IsEnum E>
129 {
130 TcpMessage* msg = GetPopMsg();
131 if (!msg)
132 return nullptr;
133
135 {
136 // 检测消息枚举
137 auto msg_id_opt = magic_enum::enum_cast<E>(msg->_head._id);
138 if (!msg_id_opt.has_value())
139 {
140 log_warn("未知协议:{}", msg->_head._id);
141 return nullptr;
142 }
143 E msg_id = msg_id_opt.value();
144
145 log_info(
146 "GetPopMsg<-[{}]:\n"
147 "消息id:{}\n"
148 "数据大小:{}\n"
149 "{}",
151 magic_enum::enum_name(msg_id),
152 msg->_head._size,
153 to_string_auto(msg->_buf));
154 }
155 return msg;
156 }
157
160
163private:
164 ClientImp* _imp;
165 Thread* _tSend;
166 Thread* _tRecv;
167 std::atomic_bool _bEnd;
168 std::atomic_bool _bValid;
169 TcpMessageList _bufListSend;
170 TcpMessageList _bufListRecv;
171 TcpMessage _msgTemp;
172
173 static void _thread_send(void*);// 发送线程
174 static void _thread_recv(void*);// 接收线程
175
176
177 void Send(uint32_t msg_id, BufferView buf);
178 void Send(uint32_t msg_id, const Buffer& buf)
179 {
180 Send(msg_id, CreateBufferView(buf));
181 }
182
183
185 {
186 if (_bufListRecv.PopFront(_msgTemp))
187 return &_msgTemp;
188 else
189 return nullptr;
190 }
191
192 bool _check_valid()
193 {
194 if (_bValid)
195 return true;
196 log_warn("未调用 Connent,或无网络权限,后续调用无效!");
197 return false;
198 }
199};
200
201class ServerImp;
204{
205public:
207 using CbDisconnect = std::function<void(int)> ;
208
209 bool Accept(uint16_t port);
210 void Run();
211
214
215
216 template<IsEnum E, IsPod T>
217 void Send(int sokect_id, E msg_id, const T& a)
218 {
221 {
222 log_info(
223 "Send->[{}]:\n"
224 "消息id:{}\n"
225 "数据大小:{}\n"
226 "{}",
227 GetRemoteAddressString(sokect_id),
228 magic_enum::enum_name(msg_id),
229 buf.size(),
230 to_string_auto(buf));
231 }
232 _send_imp(sokect_id, (uint32_t)msg_id, buf);
233 }
234
235 template<IsEnum E, IsNotPod T>
236 void Send(int sokect_id, E msg_id, const T& a)
237 {
238 Buffer buf = a.ToBuffer();
240 {
241 log_info(
242 "Send->[{}]:\n"
243 "消息id:{}\n"
244 "数据大小:{}\n"
245 "{}",
246 GetRemoteAddressString(sokect_id),
247 magic_enum::enum_name(msg_id),
248 buf.size(),
249 to_string_auto(buf));
250 }
251 _send_imp(sokect_id, (uint32_t)msg_id, buf);
252 }
253
254 std::string GetIp();
255 uint16_t GetPort();
256
257 template<IsEnum E>
259 {
260 TcpMessageServer* msg = _get_pop_msg();
261 if (!msg)
262 return nullptr;
264 {
265 // 检测消息枚举
266 auto msg_id_opt = magic_enum::enum_cast<E>(msg->_head._id);
267 if (!msg_id_opt.has_value())
268 {
269 log_warn("未知协议:{}", msg->_head._id);
270 return nullptr;
271 }
272 E msg_id = msg_id_opt.value();
273
274 log_info(
275 "GetPopMsg<-[{}]:\n"
276 "消息id:{}\n"
277 "数据大小:{}\n"
278 "{}",
280 magic_enum::enum_name(msg_id),
281 msg->_head._size,
282 to_string_auto(msg->_buf));
283 }
284 return msg;
285 }
286
287 std::string GetRemoteAddressString(int socket_id);
288
291private:
292 ServerImp* _imp;
293 Thread* _t;
294 TcpMessageServer _msgTemp;
295
296 static void _thread_run(void*);
297
298
299 void _send_imp(int sokect_id, uint32_t msg_id, BufferView buf);
300
301 TcpMessageServer* _get_pop_msg();
302};
303
304class ClientUdpImp;
307{
308public:
309 void SetAddress(std::string_view ip, uint16_t port, bool broadcast = false);
310 void Send(BufferView buf);
311 void Send(std::string_view str)
312 {
314 }
315
317 {
318 if (_bufListRecv.PopFront(_bufTemp))
319 return &_bufTemp;
320 else
321 return nullptr;
322 }
323
326private:
327 ClientUdpImp* _imp;
328 std::atomic_bool _bValid;
329 std::atomic_bool _bEnd;
330 Thread* _tSend;
331 Thread* _tRecv;
332 BufferList _bufListSend;
333 BufferList _bufListRecv;
334 Buffer _bufTemp;
335
336 static void _thread_send(void*);
337 static void _thread_recv(void*);
338
339 bool _check_valid()
340 {
341 if (_bValid)
342 return true;
343 log_warn("未调用 SetAddress,或无网络权限,后续调用无效!");
344 return false;
345 }
346};
347
348class ServerUdpImp;
351{
352 friend class ServerUdpImp;
353public:
354 bool Start(std::string_view ip, uint16_t port);
355
357 {
358 if (_listMsg.PopFront(_msgTemp))
359 return &_msgTemp;
360 else
361 return nullptr;
362 }
363
364 std::string GetIp();
365 uint16_t GetPort();
366
369private:
370 ServerUdpImp* _imp;
371 Thread* _t;
372 UdpMessageList _listMsg;
373 UdpMessage _msgTemp;
374
375 static void _thread_run(void*);
376};
377
379{
380public:
382 {
383 //Debug();
384 }
385
388 static std::string GetHostName();
389
393 static std::vector<std::string> GetIpAddressLocal(bool ipv4 = true);
397 static std::string GetIpAddressLocalFirst(bool ipv4 = true)
398 {
399 std::vector<std::string> vec = GetIpAddressLocal(ipv4);
400 return vec.empty() ? "127.0.0.1" : vec[0];
401 }
402
403 void Debug()
404 {
405 log_msg("----------------网络信息-------------\n"
406 "主机名:{}\n"
407 "本地ip:{}\n",
408 GetHostName(),
409 String::Splicing(GetIpAddressLocal()));
410 }
411};
412
413extern Network* g_net;
414}
size_t size() const
size_t size() const
TcpMessage * GetPopMsg()
void Send(E msg_id, const T &a)
std::string GetRemoteAddressString()
返回例如 192.168.1.1:7300
bool Connent(std::string_view ip, uint16_t port)
void Send(BufferView buf)
Buffer * GetPopMsg()
void Send(std::string_view str)
void SetAddress(std::string_view ip, uint16_t port, bool broadcast=false)
bool PopFront(T &a)
取第一个,顺序通过 SetQueueMode 指定,默认FIFO
static std::string GetIpAddressLocalFirst(bool ipv4=true)
返回第一个本地ip,失败返回127.0.0.1
static std::vector< std::string > GetIpAddressLocal(bool ipv4=true)
返回本地ip
static std::string GetHostName()
返回主机名
std::string GetRemoteAddressString(int socket_id)
void Run()
std::string GetIp()
uint16_t GetPort()
std::function< void(int)> CbDisconnect
断线回调
void Send(int sokect_id, E msg_id, const T &a)
bool Accept(uint16_t port)
TcpMessageServer * GetPopMsg()
void SetCbDisconnect(CbDisconnect func)
设置断线回调
bool Start(std::string_view ip, uint16_t port)
friend class ServerUdpImp
uint16_t GetPort()
std::string GetIp()
UdpMessage * GetPopMsg()
多线程队列
日志系统
#define log_warn(...)
#define log_msg(...)
#define log_info(...)
字符串相关
线程封装
constexpr bool NETWORK_LOG_CLIENT
Network * g_net
constexpr bool NETWORK_LOG_SERVER_UDP
constexpr bool NETWORK_LOG_LOW
ListMultiThread< UdpMessage > UdpMessageList
ListMultiThread< TcpMessage > TcpMessageList
std::string to_string_auto(BufferView buf, bool add_tag=false)
buf转为字符串,若不为utf8则转为16进制
ListMultiThread< Buffer > BufferList
constexpr uint8_t NETWORK_MESSAGE_TAG
constexpr bool NETWORK_LOG_CLIENT_UDP
constexpr bool NETWORK_LOG_SERVER
BufferView CreateBufferView(const Buffer &buf)
创建buffer视图(右值不能默认转换)
网络消息头
uint8_t _magic
魔法数字
uint32_t _size
数据大小
uint8_t _compress
压缩标记
uint8_t _pad
uint32_t _check
校验
uint32_t _id
协议号
E GetMsgId(uint32_t id)
E GetMsgId(uint32_t id)
std::string _ip