From 53e7dec8f0164bde6e7bb087f684a576f167be2d Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 13 Sep 2024 07:25:08 +0800 Subject: [PATCH] AI automatically translates all annotation content into English --- src/Network/Buffer.h | 75 ++++--- src/Network/BufferSock.cpp | 75 ++++--- src/Network/BufferSock.h | 3 +- src/Network/Server.cpp | 9 +- src/Network/Server.h | 24 +- src/Network/Session.h | 17 +- src/Network/Socket.cpp | 201 +++++++++++------ src/Network/Socket.h | 402 ++++++++++++++++++++++++++++------ src/Network/TcpClient.cpp | 24 +- src/Network/TcpClient.h | 57 ++++- src/Network/TcpServer.cpp | 72 ++++-- src/Network/TcpServer.h | 32 ++- src/Network/UdpServer.cpp | 105 ++++++--- src/Network/UdpServer.h | 46 +++- src/Network/sockutil.cpp | 88 +++++--- src/Network/sockutil.h | 208 +++++++++++++++++- src/Poller/EventPoller.cpp | 66 ++++-- src/Poller/EventPoller.h | 149 ++++++++++++- src/Poller/Timer.cpp | 6 +- src/Poller/Timer.h | 9 +- src/Thread/TaskExecutor.cpp | 18 +- src/Thread/TaskExecutor.h | 45 ++++ src/Thread/TaskQueue.h | 12 +- src/Thread/ThreadPool.h | 6 +- src/Thread/WorkThreadPool.cpp | 3 +- src/Thread/WorkThreadPool.h | 21 ++ src/Thread/semaphore.h | 9 + src/Util/CMD.cpp | 9 +- src/Util/File.cpp | 57 +++-- src/Util/File.h | 64 +++++- src/Util/NoticeCenter.h | 18 +- src/Util/ResourcePool.h | 38 +++- src/Util/RingBuffer.h | 58 +++-- src/Util/SSLBox.cpp | 75 ++++--- src/Util/SSLBox.h | 83 +++++++ src/Util/SSLUtil.cpp | 39 ++-- src/Util/SSLUtil.h | 72 ++++++ src/Util/SpeedStatistic.h | 12 +- src/Util/SqlConnection.h | 41 +++- src/Util/SqlPool.h | 84 ++++++- src/Util/TimeTicker.h | 25 +++ src/Util/base64.h | 10 + src/Util/function_traits.h | 9 +- src/Util/logger.h | 153 +++++++++++-- src/Util/mini.cpp | 6 +- src/Util/strptime_win.cpp | 6 +- src/Util/strptime_win.h | 6 +- src/Util/util.cpp | 30 ++- src/Util/util.h | 93 ++++++-- src/Util/uv_errno.cpp | 3 +- src/Util/uv_errno.h | 6 +- 51 files changed, 2284 insertions(+), 495 deletions(-) diff --git a/src/Network/Buffer.h b/src/Network/Buffer.h index 672451997..24f15071b 100644 --- a/src/Network/Buffer.h +++ b/src/Network/Buffer.h @@ -28,7 +28,8 @@ template struct is_pointer > : public std: template struct is_pointer : public std::true_type {}; template struct is_pointer : public std::true_type {}; -//缓存基类 +//缓存基类 [AUTO-TRANSLATED:d130ab72] +//Cache base class class Buffer : public noncopyable { public: using Ptr = std::shared_ptr; @@ -36,7 +37,8 @@ class Buffer : public noncopyable { Buffer() = default; virtual ~Buffer() = default; - //返回数据长度 + //返回数据长度 [AUTO-TRANSLATED:955f731c] + //Return data length virtual char *data() const = 0; virtual size_t size() const = 0; @@ -49,7 +51,8 @@ class Buffer : public noncopyable { } private: - //对象个数统计 + //对象个数统计 [AUTO-TRANSLATED:3b43e8c2] + //Object count statistics ObjectStatistic _statistic; }; @@ -107,7 +110,8 @@ class BufferOffset : public Buffer { using BufferString = BufferOffset; -//指针式缓存对象, +//指针式缓存对象, [AUTO-TRANSLATED:c8403290] +//Pointer-style cache object, class BufferRaw : public Buffer { public: using Ptr = std::shared_ptr; @@ -120,32 +124,38 @@ class BufferRaw : public Buffer { } } - //在写入数据时请确保内存是否越界 + //在写入数据时请确保内存是否越界 [AUTO-TRANSLATED:5602043e] + //When writing data, please ensure that the memory does not overflow char *data() const override { return _data; } - //有效数据大小 + //有效数据大小 [AUTO-TRANSLATED:b8dcbda7] + //Effective data size size_t size() const override { return _size; } - //分配内存大小 + //分配内存大小 [AUTO-TRANSLATED:cce87adf] + //Allocated memory size void setCapacity(size_t capacity) { if (_data) { do { if (capacity > _capacity) { - //请求的内存大于当前内存,那么重新分配 + //请求的内存大于当前内存,那么重新分配 [AUTO-TRANSLATED:65306424] + //If the requested memory is greater than the current memory, reallocate break; } if (_capacity < 2 * 1024) { - //2K以下,不重复开辟内存,直接复用 + //2K以下,不重复开辟内存,直接复用 [AUTO-TRANSLATED:056416c0] + //Less than 2K, do not repeatedly allocate memory, reuse directly return; } if (2 * capacity > _capacity) { - //如果请求的内存大于当前内存的一半,那么也复用 + //如果请求的内存大于当前内存的一半,那么也复用 [AUTO-TRANSLATED:c189d660] + //If the requested memory is greater than half of the current memory, also reuse return; } } while (false); @@ -156,7 +166,8 @@ class BufferRaw : public Buffer { _capacity = capacity; } - //设置有效数据大小 + //设置有效数据大小 [AUTO-TRANSLATED:efc4fb3e] + //Set valid data size virtual void setSize(size_t size) { if (size > _capacity) { throw std::invalid_argument("Buffer::setSize out of range"); @@ -164,7 +175,8 @@ class BufferRaw : public Buffer { _size = size; } - //赋值数据 + //赋值数据 [AUTO-TRANSLATED:0b91b213] + //Assign data void assign(const char *data, size_t size = 0) { if (size <= 0) { size = strlen(data); @@ -196,7 +208,8 @@ class BufferRaw : public Buffer { size_t _size = 0; size_t _capacity = 0; char *_data = nullptr; - //对象个数统计 + //对象个数统计 [AUTO-TRANSLATED:3b43e8c2] + //Object count statistics ObjectStatistic _statistic; }; @@ -275,19 +288,24 @@ class BufferLikeString : public Buffer { BufferLikeString &erase(size_t pos = 0, size_t n = std::string::npos) { if (pos == 0) { - //移除前面的数据 + //移除前面的数据 [AUTO-TRANSLATED:b025d3c5] + //Remove data from the front if (n != std::string::npos) { - //移除部分 + //移除部分 [AUTO-TRANSLATED:a650bef2] + //Remove part if (n > size()) { - //移除太多数据了 + //移除太多数据了 [AUTO-TRANSLATED:64460d15] + //Removed too much data throw std::out_of_range("BufferLikeString::erase out_of_range in head"); } - //设置起始便宜量 + //设置起始便宜量 [AUTO-TRANSLATED:7a0250bd] + //Set starting offset _erase_head += n; data()[size()] = '\0'; return *this; } - //移除全部数据 + //移除全部数据 [AUTO-TRANSLATED:3d016f79] + //Remove all data _erase_head = 0; _erase_tail = _str.size(); data()[0] = '\0'; @@ -295,9 +313,11 @@ class BufferLikeString : public Buffer { } if (n == std::string::npos || pos + n >= size()) { - //移除末尾所有数据 + //移除末尾所有数据 [AUTO-TRANSLATED:efaf1165] + //Remove all data from the end if (pos >= size()) { - //移除太多数据 + //移除太多数据 [AUTO-TRANSLATED:dc9347c3] + //Removed too much data throw std::out_of_range("BufferLikeString::erase out_of_range in tail"); } _erase_tail += size() - pos; @@ -305,9 +325,11 @@ class BufferLikeString : public Buffer { return *this; } - //移除中间的 + //移除中间的 [AUTO-TRANSLATED:fd25344c] + //Remove the middle if (pos + n > size()) { - //超过长度限制 + //超过长度限制 [AUTO-TRANSLATED:9ae84929] + //Exceeds the length limit throw std::out_of_range("BufferLikeString::erase out_of_range in middle"); } _str.erase(_erase_head + pos, n); @@ -415,14 +437,16 @@ class BufferLikeString : public Buffer { std::string substr(size_t pos, size_t n = std::string::npos) const { if (n == std::string::npos) { - //获取末尾所有的 + //获取末尾所有的 [AUTO-TRANSLATED:8a0b92b6] + //Get all at the end if (pos >= size()) { throw std::out_of_range("BufferLikeString::substr out_of_range"); } return _str.substr(_erase_head + pos, size() - pos); } - //获取部分 + //获取部分 [AUTO-TRANSLATED:d01310a4] + //Get part if (pos + n > size()) { throw std::out_of_range("BufferLikeString::substr out_of_range"); } @@ -441,7 +465,8 @@ class BufferLikeString : public Buffer { size_t _erase_head; size_t _erase_tail; std::string _str; - //对象个数统计 + //对象个数统计 [AUTO-TRANSLATED:3b43e8c2] + //Object count statistics ObjectStatistic _statistic; }; diff --git a/src/Network/BufferSock.cpp b/src/Network/BufferSock.cpp index 9dd22108c..37ca83663 100644 --- a/src/Network/BufferSock.cpp +++ b/src/Network/BufferSock.cpp @@ -97,7 +97,8 @@ class BufferCallBack { void sendCompleted(bool flag) { if (_cb) { - //全部发送成功或失败回调 + //全部发送成功或失败回调 [AUTO-TRANSLATED:6b9a9abf] + //All send success or failure callback while (!_pkt_list.empty()) { _cb(_pkt_list.front().first, flag); _pkt_list.pop_front(); @@ -109,7 +110,8 @@ class BufferCallBack { void sendFrontSuccess() { if (_cb) { - //发送成功回调 + //发送成功回调 [AUTO-TRANSLATED:52759efc] + //Send success callback _cb(_pkt_list.front().first, true); } _pkt_list.pop_front(); @@ -183,19 +185,22 @@ ssize_t BufferSendMsg::send_l(int fd, int flags) { #endif if (n >= (ssize_t)_remain_size) { - //全部写完了 + //全部写完了 [AUTO-TRANSLATED:c990f48a] + //All written _remain_size = 0; sendCompleted(true); return n; } if (n > 0) { - //部分发送成功 + //部分发送成功 [AUTO-TRANSLATED:4c240905] + //Partial send success reOffset(n); return n; } - //一个字节都未发送 + //一个字节都未发送 [AUTO-TRANSLATED:c33c611b] + //Not a single byte sent return n; } @@ -205,10 +210,12 @@ ssize_t BufferSendMsg::send(int fd, int flags) { ssize_t sent = remain_size - _remain_size; if (sent > 0) { - //部分或全部发送成功 + //部分或全部发送成功 [AUTO-TRANSLATED:a3f5e70e] + //Partial or all send success return sent; } - //一个字节都未发送成功 + //一个字节都未发送成功 [AUTO-TRANSLATED:858b63e5] + //Not a single byte sent successfully return -1; } @@ -223,18 +230,21 @@ void BufferSendMsg::reOffset(size_t n) { offset += ref.len; #endif if (offset < n) { - //此包发送完毕 + //此包发送完毕 [AUTO-TRANSLATED:759b9f0e] + //This package is sent sendFrontSuccess(); continue; } _iovec_off = i; if (offset == n) { - //这是末尾发送完毕的一个包 + //这是末尾发送完毕的一个包 [AUTO-TRANSLATED:6a3b77e4] + //This is the last package sent ++_iovec_off; sendFrontSuccess(); break; } - //这是末尾发送部分成功的一个包 + //这是末尾发送部分成功的一个包 [AUTO-TRANSLATED:64645cef] + //This is the last package partially sent size_t remain = offset - n; #if !defined(_WIN32) ref.iov_base = (char *)ref.iov_base + ref.iov_len - remain; @@ -323,12 +333,15 @@ ssize_t BufferSendTo::send(int fd, int flags) { continue; } - //n == -1的情况 + //n == -1的情况 [AUTO-TRANSLATED:305fb5bc] + //n == -1 case if (get_uv_error(true) == UV_EINTR) { - //被打断,需要继续发送 + //被打断,需要继续发送 [AUTO-TRANSLATED:6ef0b34d] + //interrupted, need to continue sending continue; } - //其他原因导致的send返回-1 + //其他原因导致的send返回-1 [AUTO-TRANSLATED:299cddb7] + //other reasons causing send to return -1 break; } return sent ? sent : -1; @@ -372,12 +385,14 @@ ssize_t BufferSendMMsg::send_l(int fd, int flags) { } while (-1 == n && UV_EINTR == get_uv_error(true)); if (n > 0) { - //部分或全部发送成功 + //部分或全部发送成功 [AUTO-TRANSLATED:a3f5e70e] + //partially or fully sent successfully reOffset(n); return n; } - //一个字节都未发送 + //一个字节都未发送 [AUTO-TRANSLATED:c33c611b] + //not a single byte sent return n; } @@ -386,10 +401,12 @@ ssize_t BufferSendMMsg::send(int fd, int flags) { while (_remain_size && send_l(fd, flags) != -1); ssize_t sent = remain_size - _remain_size; if (sent > 0) { - //部分或全部发送成功 + //部分或全部发送成功 [AUTO-TRANSLATED:a3f5e70e] + //partially or fully sent successfully return sent; } - //一个字节都未发送成功 + //一个字节都未发送成功 [AUTO-TRANSLATED:858b63e5] + //not a single byte sent successfully return -1; } @@ -400,12 +417,14 @@ void BufferSendMMsg::reOffset(size_t n) { assert(hdr.msg_len <= io.iov_len); _remain_size -= hdr.msg_len; if (hdr.msg_len == io.iov_len) { - //这个udp包全部发送成功 + //这个udp包全部发送成功 [AUTO-TRANSLATED:fce1cc86] + //this UDP packet sent successfully it = _hdrvec.erase(it); sendFrontSuccess(); continue; } - //部分发送成功 + //部分发送成功 [AUTO-TRANSLATED:4c240905] + //partially sent successfully io.iov_base = (char *)io.iov_base + hdr.msg_len; io.iov_len -= hdr.msg_len; break; @@ -444,24 +463,30 @@ BufferSendMMsg::BufferSendMMsg(List> list, SendResu BufferList::Ptr BufferList::create(List > list, SendResult cb, bool is_udp) { #if defined(_WIN32) if (is_udp) { - // sendto/send 方案,待优化 + // sendto/send 方案,待优化 [AUTO-TRANSLATED:e94184aa] + //sendto/send scheme, to be optimized return std::make_shared(std::move(list), std::move(cb), is_udp); } - // WSASend方案 + // WSASend方案 [AUTO-TRANSLATED:9ac7bb81] + //WSASend scheme return std::make_shared(std::move(list), std::move(cb)); #elif defined(__linux__) || defined(__linux) if (is_udp) { - // sendmmsg方案 + // sendmmsg方案 [AUTO-TRANSLATED:4596c2c4] + //sendmmsg scheme return std::make_shared(std::move(list), std::move(cb)); } - // sendmsg方案 + // sendmsg方案 [AUTO-TRANSLATED:8846f9c4] + //sendmsg scheme return std::make_shared(std::move(list), std::move(cb)); #else if (is_udp) { - // sendto/send 方案, 可优化? + // sendto/send 方案, 可优化? [AUTO-TRANSLATED:21dbae7c] + //sendto/send scheme, can be optimized? return std::make_shared(std::move(list), std::move(cb), is_udp); } - // sendmsg方案 + // sendmsg方案 [AUTO-TRANSLATED:8846f9c4] + //sendmsg scheme return std::make_shared(std::move(list), std::move(cb)); #endif } diff --git a/src/Network/BufferSock.h b/src/Network/BufferSock.h index d6da44465..b5a954aad 100644 --- a/src/Network/BufferSock.h +++ b/src/Network/BufferSock.h @@ -65,7 +65,8 @@ class BufferList : public noncopyable { static Ptr create(List > list, SendResult cb, bool is_udp); private: - //对象个数统计 + //对象个数统计 [AUTO-TRANSLATED:3b43e8c2] + //Object count statistics ObjectStatistic _statistic; }; diff --git a/src/Network/Server.cpp b/src/Network/Server.cpp index 155a3c969..633028534 100644 --- a/src/Network/Server.cpp +++ b/src/Network/Server.cpp @@ -24,7 +24,8 @@ SessionHelper::SessionHelper(const std::weak_ptr &server, Session::Ptr s _server = server; _session = std::move(session); _cls = std::move(cls); - //记录session至全局的map,方便后面管理 + //记录session至全局的map,方便后面管理 [AUTO-TRANSLATED:f90fce35] + //Record the session in the global map for easy management later _session_map = SessionMap::Instance().shared_from_this(); _identifier = _session->getIdentifier(); _session_map->add(_identifier, _session); @@ -32,10 +33,12 @@ SessionHelper::SessionHelper(const std::weak_ptr &server, Session::Ptr s SessionHelper::~SessionHelper() { if (!_server.lock()) { - //务必通知Session已从TcpServer脱离 + //务必通知Session已从TcpServer脱离 [AUTO-TRANSLATED:6f55a358] + //Must notify that the session has been detached from TcpServer _session->onError(SockException(Err_other, "Server shutdown")); } - //从全局map移除相关记录 + //从全局map移除相关记录 [AUTO-TRANSLATED:f0b0b2ad] + //Remove the related record from the global map _session_map->del(_identifier); } diff --git a/src/Network/Server.h b/src/Network/Server.h index 12e49c697..88d9eba61 100644 --- a/src/Network/Server.h +++ b/src/Network/Server.h @@ -17,27 +17,33 @@ namespace toolkit { -// 全局的 Session 记录对象, 方便后面管理 -// 线程安全的 +// 全局的 Session 记录对象, 方便后面管理 [AUTO-TRANSLATED:1c2725cb] +//Global Session record object, convenient for later management +// 线程安全的 [AUTO-TRANSLATED:efbca605] +//Thread-safe class SessionMap : public std::enable_shared_from_this { public: friend class SessionHelper; using Ptr = std::shared_ptr; - //单例 + //单例 [AUTO-TRANSLATED:8c2c95b4] + //Singleton static SessionMap &Instance(); ~SessionMap() = default; - //获取Session + //获取Session [AUTO-TRANSLATED:08c6e0f2] + //Get Session Session::Ptr get(const std::string &tag); void for_each_session(const std::function &cb); private: SessionMap() = default; - //移除Session + //移除Session [AUTO-TRANSLATED:b6023f67] + //Remove Session bool del(const std::string &tag); - //添加Session + //添加Session [AUTO-TRANSLATED:4bdf8277] + //Add Session bool add(const std::string &tag, const Session::Ptr &session); private: @@ -67,8 +73,10 @@ class SessionHelper { std::weak_ptr _server; }; -// server 基类, 暂时仅用于剥离 SessionHelper 对 TcpServer 的依赖 -// 后续将 TCP 与 UDP 服务通用部分加到这里. +// server 基类, 暂时仅用于剥离 SessionHelper 对 TcpServer 的依赖 [AUTO-TRANSLATED:2fe50ede] +//Server base class, temporarily only used to decouple SessionHelper from TcpServer +// 后续将 TCP 与 UDP 服务通用部分加到这里. [AUTO-TRANSLATED:3d8429f3] +//Later, the common parts of TCP and UDP services will be added here. class Server : public std::enable_shared_from_this, public mINI { public: using Ptr = std::shared_ptr; diff --git a/src/Network/Session.h b/src/Network/Session.h index 3b8a971cd..a83093e42 100644 --- a/src/Network/Session.h +++ b/src/Network/Session.h @@ -18,7 +18,8 @@ namespace toolkit { -// 会话, 用于存储一对客户端与服务端间的关系 +// 会话, 用于存储一对客户端与服务端间的关系 [AUTO-TRANSLATED:d69736ea] +//Session, used to store the relationship between a client and a server class Server; class TcpSession; class UdpSession; @@ -33,12 +34,20 @@ class Session : public SocketHelper { /** * 在创建 Session 后, Server 会把自身的配置参数通过该函数传递给 Session * @param server, 服务器对象 + * After creating a Session, the Server will pass its configuration parameters to the Session through this function + * @param server, server object + + * [AUTO-TRANSLATED:5ce03e96] */ virtual void attachServer(const Server &server) {} /** * 作为该 Session 的唯一标识符 * @return 唯一标识符 + * As the unique identifier of this Session + * @return unique identifier + + * [AUTO-TRANSLATED:3b046f26] */ std::string getIdentifier() const override; @@ -48,7 +57,8 @@ class Session : public SocketHelper { std::unique_ptr > _statistic_udp; }; -// 通过该模板可以让TCP服务器快速支持TLS +// 通过该模板可以让TCP服务器快速支持TLS [AUTO-TRANSLATED:fea218e6] +//This template allows the TCP server to quickly support TLS template class SessionWithSSL : public SessionType { public: @@ -63,7 +73,8 @@ class SessionWithSSL : public SessionType { void onRecv(const Buffer::Ptr &buf) override { _ssl_box.onRecv(buf); } - // 添加public_onRecv和public_send函数是解决较低版本gcc一个lambad中不能访问protected或private方法的bug + // 添加public_onRecv和public_send函数是解决较低版本gcc一个lambad中不能访问protected或private方法的bug [AUTO-TRANSLATED:7b16e05b] + //Adding public_onRecv and public_send functions is to solve a bug in lower versions of gcc where a lambda cannot access protected or private methods inline void public_onRecv(const Buffer::Ptr &buf) { SessionType::onRecv(buf); } inline void public_send(const Buffer::Ptr &buf) { SessionType::send(buf); } diff --git a/src/Network/Socket.cpp b/src/Network/Socket.cpp index 64a038f2d..07257f994 100644 --- a/src/Network/Socket.cpp +++ b/src/Network/Socket.cpp @@ -147,7 +147,8 @@ void Socket::setOnSendResult(onSendResult cb) { void Socket::connect(const string &url, uint16_t port, const onErrCB &con_cb_in, float timeout_sec, const string &local_ip, uint16_t local_port) { weak_ptr weak_self = shared_from_this(); - // 因为涉及到异步回调,所以在poller线程中执行确保线程安全 + // 因为涉及到异步回调,所以在poller线程中执行确保线程安全 [AUTO-TRANSLATED:e4b29f5e] + //Because it involves asynchronous callbacks, execute in the poller thread to ensure thread safety _poller->async([=] { if (auto strong_self = weak_self.lock()) { strong_self->connect_l(url, port, con_cb_in, timeout_sec, local_ip, local_port); @@ -156,7 +157,8 @@ void Socket::connect(const string &url, uint16_t port, const onErrCB &con_cb_in, } void Socket::connect_l(const string &url, uint16_t port, const onErrCB &con_cb_in, float timeout_sec, const string &local_ip, uint16_t local_port) { - // 重置当前socket + // 重置当前socket [AUTO-TRANSLATED:b38093a6] + //Reset the current socket closeSock(); weak_ptr weak_self = shared_from_this(); @@ -180,7 +182,8 @@ void Socket::connect_l(const string &url, uint16_t port, const onErrCB &con_cb_i return; } - // 监听该socket是否可写,可写表明已经连接服务器成功 + // 监听该socket是否可写,可写表明已经连接服务器成功 [AUTO-TRANSLATED:e9809ee3] + //Listen for whether the socket is writable, writable indicates that the connection to the server is successful int result = strong_self->_poller->addEvent(sock->rawFd(), EventPoller::Event_Write | EventPoller::Event_Error, [weak_self, sock, con_cb](int event) { if (auto strong_self = weak_self.lock()) { strong_self->onConnected(sock, con_cb); @@ -190,12 +193,14 @@ void Socket::connect_l(const string &url, uint16_t port, const onErrCB &con_cb_i if (result == -1) { con_cb(SockException(Err_other, std::string("add event to poller failed when start connect:") + get_uv_errmsg())); } else { - // 先创建SockFD对象,防止SockNum由于未执行delEvent无法析构 + // 先创建SockFD对象,防止SockNum由于未执行delEvent无法析构 [AUTO-TRANSLATED:99d4e610] + //First create the SockFD object to prevent SockNum from being destructed due to not executing delEvent strong_self->setSock(sock); } }); - // 连接超时定时器 + // 连接超时定时器 [AUTO-TRANSLATED:1f4471b2] + //Connection timeout timer _con_timer = std::make_shared(timeout_sec,[weak_self, con_cb]() { con_cb(SockException(Err_timeout, uv_strerror(UV_ETIMEDOUT))); return false; @@ -208,7 +213,8 @@ void Socket::connect_l(const string &url, uint16_t port, const onErrCB &con_cb_i auto poller = _poller; weak_ptr> weak_task = async_con_cb; WorkThreadPool::Instance().getExecutor()->async([url, port, local_ip, local_port, weak_task, poller]() { - // 阻塞式dns解析放在后台线程执行 + // 阻塞式dns解析放在后台线程执行 [AUTO-TRANSLATED:e54694ea] + //Blocking DNS resolution is executed in the background thread int fd = SockUtil::connect(url.data(), port, true, local_ip.data(), local_port); auto sock = fd == -1 ? nullptr : std::make_shared(fd, SockNum::Sock_TCP); poller->async([sock, weak_task]() { @@ -224,17 +230,21 @@ void Socket::connect_l(const string &url, uint16_t port, const onErrCB &con_cb_i void Socket::onConnected(const SockNum::Ptr &sock, const onErrCB &cb) { auto err = getSockErr(sock->rawFd(), false); if (err) { - // 连接失败 + // 连接失败 [AUTO-TRANSLATED:50e99e6b] + //Connection failed cb(err); return; } - // 更新地址信息 + // 更新地址信息 [AUTO-TRANSLATED:bacb739d] + //Update address information setSock(sock); - // 先删除之前的可写事件监听 + // 先删除之前的可写事件监听 [AUTO-TRANSLATED:ca424913] + //First delete the previous writable event listener _poller->delEvent(sock->rawFd(), [sock](bool) {}); if (!attachEvent(sock)) { - // 连接失败 + // 连接失败 [AUTO-TRANSLATED:50e99e6b] + //Connection failed cb(SockException(Err_other, "add event to poller failed when connected")); return; } @@ -245,14 +255,16 @@ void Socket::onConnected(const SockNum::Ptr &sock, const onErrCB &cb) { _sock_fd->setConnected(); } } - // 连接成功 + // 连接成功 [AUTO-TRANSLATED:7db0fbc4] + //Connection successful cb(err); } bool Socket::attachEvent(const SockNum::Ptr &sock) { weak_ptr weak_self = shared_from_this(); if (sock->type() == SockNum::Sock_TCP_Server) { - // tcp服务器 + // tcp服务器 [AUTO-TRANSLATED:f4b9757f] + //TCP server auto result = _poller->addEvent(sock->rawFd(), EventPoller::Event_Read | EventPoller::Event_Error, [weak_self, sock](int event) { if (auto strong_self = weak_self.lock()) { strong_self->onAccept(sock, event); @@ -261,7 +273,8 @@ bool Socket::attachEvent(const SockNum::Ptr &sock) { return -1 != result; } - // tcp客户端或udp + // tcp客户端或udp [AUTO-TRANSLATED:00c16e7f] + //TCP client or UDP auto read_buffer = _poller->getSharedBuffer(sock->type() == SockNum::Sock_UDP); auto result = _poller->addEvent(sock->rawFd(), EventPoller::Event_Read | EventPoller::Event_Error | EventPoller::Event_Write, [weak_self, sock, read_buffer](int event) { auto strong_self = weak_self.lock(); @@ -311,14 +324,16 @@ ssize_t Socket::onRead(const SockNum::Ptr &sock, const SocketRecvBuffer::Ptr &bu ret += nread; if (_enable_speed) { - // 更新接收速率 + // 更新接收速率 [AUTO-TRANSLATED:1e24774c] + //Update receive rate _recv_speed += nread; } auto &buf = buffer->getBuffer(0); auto &addr = buffer->getAddress(0); try { - // 此处捕获异常,目的是防止数据未读尽,epoll边沿触发失效的问题 + // 此处捕获异常,目的是防止数据未读尽,epoll边沿触发失效的问题 [AUTO-TRANSLATED:2f3f813b] + //Catch exception here, the purpose is to prevent data from not being read completely, and the epoll edge trigger fails LOCK_GUARD(_mtx_event); _on_multi_read(&buf, &addr, count); } catch (std::exception &ex) { @@ -345,7 +360,8 @@ bool Socket::emitErr(const SockException &err) noexcept { } catch (std::exception &ex) { ErrorL << "Exception occurred when emit on_err: " << ex.what(); } - // 延后关闭socket,只移除其io事件,防止Session对象析构时获取fd相关信息失败 + // 延后关闭socket,只移除其io事件,防止Session对象析构时获取fd相关信息失败 [AUTO-TRANSLATED:db5a0958] + //Delay closing the socket, only remove its IO event, to prevent Session object destruction from failing to get fd related information strong_self->closeSock(false); }); return true; @@ -372,7 +388,8 @@ ssize_t Socket::send(Buffer::Ptr buf, struct sockaddr *addr, socklen_t addr_len, if (!_udp_send_dst) { return send_l(std::move(buf), false, try_flush); } - // 本次发送未指定目标地址,但是目标定制已通过bindPeerAddr指定 + // 本次发送未指定目标地址,但是目标定制已通过bindPeerAddr指定 [AUTO-TRANSLATED:afb6ce35] + //This send did not specify a target address, but the target is customized through bindPeerAddr addr = (struct sockaddr *)_udp_send_dst.get(); addr_len = SockUtil::get_sock_len(addr); } @@ -403,17 +420,21 @@ int Socket::flushAll() { LOCK_GUARD(_mtx_sock_fd); if (!_sock_fd) { - // 如果已断开连接或者发送超时 + // 如果已断开连接或者发送超时 [AUTO-TRANSLATED:2e25a648] + //If the connection is already disconnected or the send has timed out return -1; } if (_sendable) { - // 该socket可写 + // 该socket可写 [AUTO-TRANSLATED:9b37b658] + //The socket is writable return flushData(_sock_fd->sockNum(), false) ? 0 : -1; } - // 该socket不可写,判断发送超时 + // 该socket不可写,判断发送超时 [AUTO-TRANSLATED:cad042e3] + //The socket is not writable, judging send timeout if (_send_flush_ticker.elapsedTime() > _max_send_buffer_ms) { - // 如果发送列队中最老的数据距今超过超时时间限制,那么就断开socket连接 + // 如果发送列队中最老的数据距今超过超时时间限制,那么就断开socket连接 [AUTO-TRANSLATED:19ee680e] + //If the oldest data in the send queue exceeds the timeout limit, disconnect the socket connection emitErr(SockException(Err_other, "socket send timeout")); return -1; } @@ -533,33 +554,41 @@ int Socket::onAccept(const SockNum::Ptr &sock, int event) noexcept { } while (-1 == fd && UV_EINTR == get_uv_error(true)); if (fd == -1) { - // accept失败 + // accept失败 [AUTO-TRANSLATED:496cc51e] + //Accept failed int err = get_uv_error(true); if (err == UV_EAGAIN) { - // 没有新连接 + // 没有新连接 [AUTO-TRANSLATED:4ddd97d6] + //No new connection return 0; } auto ex = toSockException(err); // emitErr(ex); https://github.com/ZLMediaKit/ZLMediaKit/issues/2946 ErrorL << "Accept socket failed: " << ex.what(); - // 可能打开的文件描述符太多了:UV_EMFILE/UV_ENFILE + // 可能打开的文件描述符太多了:UV_EMFILE/UV_ENFILE [AUTO-TRANSLATED:ecd1b4f1] + //Possibly too many open file descriptors: UV_EMFILE/UV_ENFILE #if (defined(HAS_EPOLL) && !defined(_WIN32)) || defined(HAS_KQUEUE) - // 边缘触发,还需要手动再触发accept事件, + // 边缘触发,还需要手动再触发accept事件, [AUTO-TRANSLATED:85fa9030] + //Edge trigger, need to manually trigger the accept event again // wepoll, Edge-triggered (`EPOLLET`) mode isn't supported. std::weak_ptr weak_self = shared_from_this(); _poller->doDelayTask(100, [weak_self, sock]() { if (auto strong_self = weak_self.lock()) { - // 100ms后再处理accept事件,说不定已经有空闲的fd + // 100ms后再处理accept事件,说不定已经有空闲的fd [AUTO-TRANSLATED:532951a2] + //Process the accept event again after 100ms, maybe there are available fds strong_self->onAccept(sock, EventPoller::Event_Read); } return 0; }); - // 暂时不处理accept事件,等待100ms后手动触发onAccept(只有EAGAIN读空后才能通过epoll再次触发事件) + // 暂时不处理accept事件,等待100ms后手动触发onAccept(只有EAGAIN读空后才能通过epoll再次触发事件) [AUTO-TRANSLATED:32636aea] + //Temporarily do not process the accept event, wait 100ms and manually trigger onAccept (can only be triggered again through epoll after EAGAIN reads empty) return -1; #else - // 水平触发;休眠10ms,防止无谓的accept失败 + // 水平触发;休眠10ms,防止无谓的accept失败 [AUTO-TRANSLATED:6f8349bb] + //Level trigger; sleep 10ms to prevent unnecessary accept failures this_thread::sleep_for(std::chrono::milliseconds(10)); - // 暂时不处理accept事件,由于是水平触发,下次还会再次自动进入onAccept函数 + // 暂时不处理accept事件,由于是水平触发,下次还会再次自动进入onAccept函数 [AUTO-TRANSLATED:9aec1432] + //Temporarily do not process the accept event, as it is level trigger, it will automatically enter the onAccept function again next time return -1; #endif } @@ -574,9 +603,11 @@ int Socket::onAccept(const SockNum::Ptr &sock, int event) noexcept { Socket::Ptr peer_sock; try { - // 此处捕获异常,目的是防止socket未accept尽,epoll边沿触发失效的问题 + // 此处捕获异常,目的是防止socket未accept尽,epoll边沿触发失效的问题 [AUTO-TRANSLATED:523d496d] + //Catch exceptions here to prevent the problem of epoll edge trigger failure when the socket is not fully accepted LOCK_GUARD(_mtx_event); - // 拦截Socket对象的构造 + // 拦截Socket对象的构造 [AUTO-TRANSLATED:b38b67b9] + //Intercept the Socket object's constructor peer_sock = _on_before_accept(_poller); } catch (std::exception &ex) { ErrorL << "Exception occurred when emit on_before_accept: " << ex.what(); @@ -585,21 +616,26 @@ int Socket::onAccept(const SockNum::Ptr &sock, int event) noexcept { } if (!peer_sock) { - // 此处是默认构造行为,也就是子Socket共用父Socket的poll线程并且关闭互斥锁 + // 此处是默认构造行为,也就是子Socket共用父Socket的poll线程并且关闭互斥锁 [AUTO-TRANSLATED:6c057de0] + //This is the default construction behavior, which means the child Socket shares the parent Socket's poll thread and closes the mutex lock peer_sock = Socket::createSocket(_poller, false); } auto sock = std::make_shared(fd, SockNum::Sock_TCP); - // 设置好fd,以备在onAccept事件中可以正常访问该fd + // 设置好fd,以备在onAccept事件中可以正常访问该fd [AUTO-TRANSLATED:e3e3c225] + //Set the fd properly, so that it can be accessed normally in the onAccept event peer_sock->setSock(sock); - // 赋值peer ip,防止在执行setSock时,fd已经被reset断开 + // 赋值peer ip,防止在执行setSock时,fd已经被reset断开 [AUTO-TRANSLATED:7ca197db] + //Assign the peer ip to prevent the fd from being reset and disconnected when executing setSock memcpy(&peer_sock->_peer_addr, &peer_addr, addr_len); shared_ptr completed(nullptr, [peer_sock, sock](void *) { try { - // 然后把该fd加入poll监听(确保先触发onAccept事件然后再触发onRead等事件) + // 然后把该fd加入poll监听(确保先触发onAccept事件然后再触发onRead等事件) [AUTO-TRANSLATED:45618926] + //Then add the fd to the poll monitoring (ensure that the onAccept event is triggered first, followed by onRead and other events) if (!peer_sock->attachEvent(sock)) { - // 加入poll监听失败,触发onErr事件,通知该Socket无效 + // 加入poll监听失败,触发onErr事件,通知该Socket无效 [AUTO-TRANSLATED:e81fd478] + //If adding to poll monitoring fails, trigger the onErr event to notify that the Socket is invalid peer_sock->emitErr(SockException(Err_eof, "add event to poller failed when accept a socket")); } } catch (std::exception &ex) { @@ -608,9 +644,11 @@ int Socket::onAccept(const SockNum::Ptr &sock, int event) noexcept { }); try { - // 此处捕获异常,目的是防止socket未accept尽,epoll边沿触发失效的问题 + // 此处捕获异常,目的是防止socket未accept尽,epoll边沿触发失效的问题 [AUTO-TRANSLATED:523d496d] + //Catch exceptions here to prevent the problem of socket not being accepted and epoll edge triggering failure LOCK_GUARD(_mtx_event); - // 先触发onAccept事件,此时应该监听该Socket的onRead等事件 + // 先触发onAccept事件,此时应该监听该Socket的onRead等事件 [AUTO-TRANSLATED:29734871] + //First trigger the onAccept event, at this point, you should listen for onRead and other events of the Socket _on_accept(peer_sock, completed); } catch (std::exception &ex) { ErrorL << "Exception occurred when emit on_accept: " << ex.what(); @@ -684,7 +722,8 @@ string Socket::getIdentifier() const { bool Socket::flushData(const SockNum::Ptr &sock, bool poller_thread) { decltype(_send_buf_sending) send_buf_sending_tmp; { - // 转移出二级缓存 + // 转移出二级缓存 [AUTO-TRANSLATED:a54264d2] + //Transfer out of the secondary cache LOCK_GUARD(_mtx_send_buf_sending); if (!_send_buf_sending.empty()) { send_buf_sending_tmp.swap(_send_buf_sending); @@ -695,14 +734,17 @@ bool Socket::flushData(const SockNum::Ptr &sock, bool poller_thread) { _send_flush_ticker.resetTime(); do { { - // 二级发送缓存为空,那么我们接着消费一级缓存中的数据 + // 二级发送缓存为空,那么我们接着消费一级缓存中的数据 [AUTO-TRANSLATED:8ddb2962] + //The secondary send cache is empty, so we continue to consume data from the primary cache LOCK_GUARD(_mtx_send_buf_waiting); if (!_send_buf_waiting.empty()) { - // 把一级缓中数数据放置到二级缓存中并清空 + // 把一级缓中数数据放置到二级缓存中并清空 [AUTO-TRANSLATED:4884aa58] + //Put the data from the first-level cache into the second-level cache and clear it LOCK_GUARD(_mtx_event); auto send_result = _enable_speed ? [this](const Buffer::Ptr &buffer, bool send_success) { if (send_success) { - //更新发送速率 + //更新发送速率 [AUTO-TRANSLATED:e35a1eba] + //Update the sending rate _send_speed += buffer->size(); } LOCK_GUARD(_mtx_event); @@ -714,10 +756,13 @@ bool Socket::flushData(const SockNum::Ptr &sock, bool poller_thread) { break; } } - // 如果一级缓存也为空,那么说明所有数据均写入socket了 + // 如果一级缓存也为空,那么说明所有数据均写入socket了 [AUTO-TRANSLATED:6ae9ef8a] + //If the first-level cache is also empty, it means that all data has been written to the socket if (poller_thread) { - // poller线程触发该函数,那么该socket应该已经加入了可写事件的监听; - // 那么在数据列队清空的情况下,我们需要关闭监听以免触发无意义的事件回调 + // poller线程触发该函数,那么该socket应该已经加入了可写事件的监听; [AUTO-TRANSLATED:5a8e123d] + //The poller thread triggers this function, so the socket should have been added to the writable event listening + // 那么在数据列队清空的情况下,我们需要关闭监听以免触发无意义的事件回调 [AUTO-TRANSLATED:0fb35573] + //So, in the case of data queue clearing, we need to close the listening to avoid triggering meaningless event callbacks stopWriteAbleEvent(sock); onFlushed(); } @@ -729,55 +774,70 @@ bool Socket::flushData(const SockNum::Ptr &sock, bool poller_thread) { auto &packet = send_buf_sending_tmp.front(); auto n = packet->send(sock->rawFd(), _sock_flags); if (n > 0) { - // 全部或部分发送成功 + // 全部或部分发送成功 [AUTO-TRANSLATED:0721ed7c] + //All or part of the data was sent successfully if (packet->empty()) { - // 全部发送成功 + // 全部发送成功 [AUTO-TRANSLATED:38a7d0ac] + //All data was sent successfully send_buf_sending_tmp.pop_front(); continue; } - // 部分发送成功 + // 部分发送成功 [AUTO-TRANSLATED:bd6609dd] + //Part of the data was sent successfully if (!poller_thread) { - // 如果该函数是poller线程触发的,那么该socket应该已经加入了可写事件的监听,所以我们不需要再次加入监听 + // 如果该函数是poller线程触发的,那么该socket应该已经加入了可写事件的监听,所以我们不需要再次加入监听 [AUTO-TRANSLATED:917049f0] + //If this function is triggered by the poller thread, the socket should have been added to the writable event listening, so we don't need to add listening again startWriteAbleEvent(sock); } break; } - // 一个都没发送成功 + // 一个都没发送成功 [AUTO-TRANSLATED:a3b4f257] + //None of the data was sent successfully int err = get_uv_error(true); if (err == UV_EAGAIN) { - // 等待下一次发送 + // 等待下一次发送 [AUTO-TRANSLATED:22980496] + //Wait for the next send if (!poller_thread) { - // 如果该函数是poller线程触发的,那么该socket应该已经加入了可写事件的监听,所以我们不需要再次加入监听 + // 如果该函数是poller线程触发的,那么该socket应该已经加入了可写事件的监听,所以我们不需要再次加入监听 [AUTO-TRANSLATED:917049f0] + //If this function is triggered by the poller thread, the socket should have already been added to the writable event listener, so we don't need to add it again startWriteAbleEvent(sock); } break; } - // 其他错误代码,发生异常 + // 其他错误代码,发生异常 [AUTO-TRANSLATED:14cca084] + //Other error codes, an exception occurred if (sock->type() == SockNum::Sock_UDP) { - // udp发送异常,把数据丢弃 + // udp发送异常,把数据丢弃 [AUTO-TRANSLATED:3a7d095d] + //UDP send exception, discard the data send_buf_sending_tmp.pop_front(); WarnL << "Send udp socket[" << sock << "] failed, data ignored: " << uv_strerror(err); continue; } - // tcp发送失败时,触发异常 + // tcp发送失败时,触发异常 [AUTO-TRANSLATED:06f06449] + //TCP send failed, trigger an exception emitErr(toSockException(err)); return false; } - // 回滚未发送完毕的数据 + // 回滚未发送完毕的数据 [AUTO-TRANSLATED:9f67c1be] + //Roll back the unsent data if (!send_buf_sending_tmp.empty()) { - // 有剩余数据 + // 有剩余数据 [AUTO-TRANSLATED:14a89b15] + //There is remaining data LOCK_GUARD(_mtx_send_buf_sending); send_buf_sending_tmp.swap(_send_buf_sending); _send_buf_sending.append(send_buf_sending_tmp); - // 二级缓存未全部发送完毕,说明该socket不可写,直接返回 + // 二级缓存未全部发送完毕,说明该socket不可写,直接返回 [AUTO-TRANSLATED:2d7f9f2f] + //The secondary cache has not been sent completely, indicating that the socket is not writable, return directly return true; } - // 二级缓存已经全部发送完毕,说明该socket还可写,我们尝试继续写 - // 如果是poller线程,我们尝试再次写一次(因为可能其他线程调用了send函数又有新数据了) + // 二级缓存已经全部发送完毕,说明该socket还可写,我们尝试继续写 [AUTO-TRANSLATED:2c2bc316] + //The secondary cache has been sent completely, indicating that the socket is still writable, we try to continue writing + // 如果是poller线程,我们尝试再次写一次(因为可能其他线程调用了send函数又有新数据了) [AUTO-TRANSLATED:392684a8] + //If it's the poller thread, we try to write again (because other threads may have called the send function and there is new data) return poller_thread ? flushData(sock, poller_thread) : true; } @@ -795,23 +855,27 @@ void Socket::onWriteAble(const SockNum::Ptr &sock) { } if (empty_waiting && empty_sending) { - // 数据已经清空了,我们停止监听可写事件 + // 数据已经清空了,我们停止监听可写事件 [AUTO-TRANSLATED:751f7e4e] + //Data has been cleared, we stop listening for writable events stopWriteAbleEvent(sock); } else { - // socket可写,我们尝试发送剩余的数据 + // socket可写,我们尝试发送剩余的数据 [AUTO-TRANSLATED:d66e0207] + //Socket is writable, we try to send the remaining data flushData(sock, true); } } void Socket::startWriteAbleEvent(const SockNum::Ptr &sock) { - // 开始监听socket可写事件 + // 开始监听socket可写事件 [AUTO-TRANSLATED:31ba90c5] + //Start listening for socket writable events _sendable = false; int flag = _enable_recv ? EventPoller::Event_Read : 0; _poller->modifyEvent(sock->rawFd(), flag | EventPoller::Event_Error | EventPoller::Event_Write, [sock](bool) {}); } void Socket::stopWriteAbleEvent(const SockNum::Ptr &sock) { - // 停止监听socket可写事件 + // 停止监听socket可写事件 [AUTO-TRANSLATED:4eb5b241] + //Stop listening for socket writable events _sendable = true; int flag = _enable_recv ? EventPoller::Event_Read : 0; _poller->modifyEvent(sock->rawFd(), flag | EventPoller::Event_Error, [sock](bool) {}); @@ -823,7 +887,8 @@ void Socket::enableRecv(bool enabled) { } _enable_recv = enabled; int read_flag = _enable_recv ? EventPoller::Event_Read : 0; - // 可写时,不监听可写事件 + // 可写时,不监听可写事件 [AUTO-TRANSLATED:6a50e751] + //Do not listen for writable events when writable int send_flag = _sendable ? 0 : EventPoller::Event_Write; _poller->modifyEvent(rawFD(), read_flag | send_flag | EventPoller::Event_Error); } @@ -885,11 +950,13 @@ bool Socket::bindPeerAddr(const struct sockaddr *dst_addr, socklen_t addr_len, b } addr_len = addr_len ? addr_len : SockUtil::get_sock_len(dst_addr); if (soft_bind) { - // 软绑定,只保存地址 + // 软绑定,只保存地址 [AUTO-TRANSLATED:e74e9b53] + //Soft bind, only save the address _udp_send_dst = std::make_shared(); memcpy(_udp_send_dst.get(), dst_addr, addr_len); } else { - // 硬绑定后,取消软绑定,防止memcpy目标地址的性能损失 + // 硬绑定后,取消软绑定,防止memcpy目标地址的性能损失 [AUTO-TRANSLATED:f3f26702] + //After hard binding, cancel soft binding to prevent performance loss of memcpy target address _udp_send_dst = nullptr; if (-1 == ::connect(_sock_fd->rawFd(), dst_addr, addr_len)) { WarnL << "Connect socket to peer address failed: " << SockUtil::inet_ntoa(dst_addr); diff --git a/src/Network/Socket.h b/src/Network/Socket.h index 2155eeb22..5905903ea 100644 --- a/src/Network/Socket.h +++ b/src/Network/Socket.h @@ -43,13 +43,16 @@ namespace toolkit { #define FLAG_DONTWAIT 0 #endif //MSG_DONTWAIT -//默认的socket flags:不触发SIGPIPE,非阻塞发送 +//默认的socket flags:不触发SIGPIPE,非阻塞发送 [AUTO-TRANSLATED:fefc4946] +//Default socket flags: do not trigger SIGPIPE, non-blocking send #define SOCKET_DEFAULE_FLAGS (FLAG_NOSIGNAL | FLAG_DONTWAIT ) -//发送超时时间,如果在规定时间内一直没有发送数据成功,那么将触发onErr事件 +//发送超时时间,如果在规定时间内一直没有发送数据成功,那么将触发onErr事件 [AUTO-TRANSLATED:9c5d8d87] +//Send timeout time, if no data is sent successfully within the specified time, the onErr event will be triggered #define SEND_TIME_OUT_SEC 10 -//错误类型枚举 +//错误类型枚举 [AUTO-TRANSLATED:c85ff6f6] +//Error type enumeration typedef enum { Err_success = 0, //成功 success Err_eof, //eof @@ -61,7 +64,8 @@ typedef enum { Err_other = 0xFF,//其他错误 other error } ErrCode; -//错误信息类 +//错误信息类 [AUTO-TRANSLATED:5d337296] +//Error message class class SockException : public std::exception { public: SockException(ErrCode code = Err_success, const std::string &msg = "", int custom_code = 0) { @@ -70,29 +74,34 @@ class SockException : public std::exception { _custom_code = custom_code; } - //重置错误 + //重置错误 [AUTO-TRANSLATED:d421942a] + //Reset error void reset(ErrCode code, const std::string &msg, int custom_code = 0) { _msg = msg; _code = code; _custom_code = custom_code; } - //错误提示 + //错误提示 [AUTO-TRANSLATED:989d5b29] + //Error prompt const char *what() const noexcept override { return _msg.c_str(); } - //错误代码 + //错误代码 [AUTO-TRANSLATED:06930b2e] + //Error code ErrCode getErrCode() const { return _code; } - //用户自定义错误代码 + //用户自定义错误代码 [AUTO-TRANSLATED:aef77c4e] + //User-defined error code int getCustomCode() const { return _custom_code; } - //判断是否真的有错 + //判断是否真的有错 [AUTO-TRANSLATED:b12fad69] + //Determine if there is really an error operator bool() const { return _code != Err_success; } @@ -103,7 +112,8 @@ class SockException : public std::exception { std::string _msg; }; -//std::cout等输出流可以直接输出SockException对象 +//std::cout等输出流可以直接输出SockException对象 [AUTO-TRANSLATED:9b0a61e5] +//std::cout and other output streams can directly output SockException objects std::ostream &operator<<(std::ostream &ost, const SockException &err); class SockNum { @@ -126,7 +136,8 @@ class SockNum { #if defined (OS_IPHONE) unsetSocketOfIOS(_fd); #endif //OS_IPHONE - // 停止socket收发能力 + // 停止socket收发能力 [AUTO-TRANSLATED:73526f07] + //Stop socket send and receive capability #if defined(_WIN32) ::shutdown(_fd, SD_BOTH); #else @@ -162,9 +173,12 @@ class SockNum { SockType _type; }; -//socket 文件描述符的包装 -//在析构时自动溢出监听并close套接字 -//防止描述符溢出 +//socket 文件描述符的包装 [AUTO-TRANSLATED:d6705c7a] +//Socket file descriptor wrapper +//在析构时自动溢出监听并close套接字 [AUTO-TRANSLATED:3d9c96d9] +//Automatically overflow listening and close socket when destructing +//防止描述符溢出 [AUTO-TRANSLATED:17c2f2f0] +//Prevent descriptor overflow class SockFD : public noncopyable { public: using Ptr = std::shared_ptr; @@ -173,6 +187,11 @@ class SockFD : public noncopyable { * 创建一个fd对象 * @param num 文件描述符,int数字 * @param poller 事件监听器 + * Create an fd object + * @param num File descriptor, int number + * @param poller Event listener + + * [AUTO-TRANSLATED:2eb468c4] */ SockFD(SockNum::Ptr num, const EventPoller::Ptr &poller) { _num = std::move(num); @@ -183,6 +202,11 @@ class SockFD : public noncopyable { * 复制一个fd对象 * @param that 源对象 * @param poller 事件监听器 + * Copy an fd object + * @param that Source object + * @param poller Event listener + + * [AUTO-TRANSLATED:51fca132] */ SockFD(const SockFD &that, const EventPoller::Ptr &poller) { _num = that._num; @@ -197,7 +221,8 @@ class SockFD : public noncopyable { void delEvent() { if (_poller) { auto num = _num; - // 移除io事件成功后再close fd + // 移除io事件成功后再close fd [AUTO-TRANSLATED:4b5e429f] + //Remove IO event successfully before closing fd _poller->delEvent(num->rawFd(), [num](bool) {}); _poller = nullptr; } @@ -259,15 +284,20 @@ class SockInfo { SockInfo() = default; virtual ~SockInfo() = default; - //获取本机ip + //获取本机ip [AUTO-TRANSLATED:02d3901d] + //Get local IP virtual std::string get_local_ip() = 0; - //获取本机端口号 + //获取本机端口号 [AUTO-TRANSLATED:f883cf62] + //Get local port number virtual uint16_t get_local_port() = 0; - //获取对方ip + //获取对方ip [AUTO-TRANSLATED:f042aa78] + //Get peer IP virtual std::string get_peer_ip() = 0; - //获取对方端口号 + //获取对方端口号 [AUTO-TRANSLATED:0d085eca] + //Get the peer's port number virtual uint16_t get_peer_port() = 0; - //获取标识符 + //获取标识符 [AUTO-TRANSLATED:e623608c] + //Get the identifier virtual std::string getIdentifier() const { return ""; } }; @@ -277,29 +307,41 @@ class SockInfo { #define WarnP(ptr) WarnL << ptr->getIdentifier() << "(" << ptr->get_peer_ip() << ":" << ptr->get_peer_port() << ") " #define ErrorP(ptr) ErrorL << ptr->getIdentifier() << "(" << ptr->get_peer_ip() << ":" << ptr->get_peer_port() << ") " -//异步IO Socket对象,包括tcp客户端、服务器和udp套接字 +//异步IO Socket对象,包括tcp客户端、服务器和udp套接字 [AUTO-TRANSLATED:8d4fc5c2] +//Asynchronous IO Socket object, including TCP client, server, and UDP socket class Socket : public std::enable_shared_from_this, public noncopyable, public SockInfo { public: using Ptr = std::shared_ptr; - //接收数据回调 + //接收数据回调 [AUTO-TRANSLATED:e3b7ff16] + //Receive data callback using onReadCB = std::function; using onMultiReadCB = std::function; - //发生错误回调 + //发生错误回调 [AUTO-TRANSLATED:d6897b99] + //Error callback using onErrCB = std::function; - //tcp监听接收到连接请求 + //tcp监听接收到连接请求 [AUTO-TRANSLATED:c4e1b206] + //TCP listen receives a connection request using onAcceptCB = std::function &complete)>; - //socket发送缓存清空事件,返回true代表下次继续监听该事件,否则停止 + //socket发送缓存清空事件,返回true代表下次继续监听该事件,否则停止 [AUTO-TRANSLATED:2dd1c036] + //Socket send buffer is cleared event, returns true to continue listening for the event next time, otherwise stops using onFlush = std::function; - //在接收到连接请求前,拦截Socket默认生成方式 + //在接收到连接请求前,拦截Socket默认生成方式 [AUTO-TRANSLATED:2f07f268] + //Intercept the default generation method of the Socket before receiving a connection request using onCreateSocket = std::function; - //发送buffer成功与否回调 + //发送buffer成功与否回调 [AUTO-TRANSLATED:4db5efb8] + //Send buffer success or failure callback using onSendResult = BufferList::SendResult; /** * 构造socket对象,尚未有实质操作 * @param poller 绑定的poller线程 * @param enable_mutex 是否启用互斥锁(接口是否线程安全) + * Construct a socket object, no actual operation yet + * @param poller The bound poller thread + * @param enable_mutex Whether to enable the mutex (whether the interface is thread-safe) + + * [AUTO-TRANSLATED:39bd767a] */ static Ptr createSocket(const EventPoller::Ptr &poller = nullptr, bool enable_mutex = true); ~Socket() override; @@ -312,6 +354,15 @@ class Socket : public std::enable_shared_from_this, public noncopyable, * @param timeout_sec 超时时间 * @param local_ip 绑定本地网卡ip * @param local_port 绑定本地网卡端口号 + * Create a TCP client and connect to the server asynchronously + * @param url Target server IP or domain name + * @param port Target server port + * @param con_cb Result callback + * @param timeout_sec Timeout time + * @param local_ip Local network card IP to bind + * @param local_port Local network card port number to bind + + * [AUTO-TRANSLATED:4f6c0d3e] */ void connect(const std::string &url, uint16_t port, const onErrCB &con_cb, float timeout_sec = 5, const std::string &local_ip = "::", uint16_t local_port = 0); @@ -321,6 +372,13 @@ class Socket : public std::enable_shared_from_this, public noncopyable, * @param local_ip 监听的网卡ip * @param backlog tcp最大积压数 * @return 是否成功 + * Create a TCP listening server + * @param port Listening port, 0 for random + * @param local_ip Network card IP to listen on + * @param backlog Maximum TCP backlog + * @return Whether successful + + * [AUTO-TRANSLATED:c90ff571] */ bool listen(uint16_t port, const std::string &local_ip = "::", int backlog = 1024); @@ -329,6 +387,12 @@ class Socket : public std::enable_shared_from_this, public noncopyable, * @param port 绑定的端口为0则随机 * @param local_ip 绑定的网卡ip * @return 是否成功 + * Create a UDP socket, UDP is connectionless, so it can be used as a server and client + * @param port Port to bind, 0 for random + * @param local_ip Network card IP to bind + * @return Whether successful + + * [AUTO-TRANSLATED:e96342b5] */ bool bindUdpSock(uint16_t port, const std::string &local_ip = "::", bool enable_reuse = true); @@ -336,6 +400,11 @@ class Socket : public std::enable_shared_from_this, public noncopyable, * 包装外部fd,本对象负责close fd * 内部会设置fd为NoBlocked,NoSigpipe,CloExec * 其他设置需要自行使用SockUtil进行设置 + * Wrap an external file descriptor, this object is responsible for closing the file descriptor + * Internally, the file descriptor will be set to NoBlocked, NoSigpipe, CloExec + * Other settings need to be set manually using SockUtil + + * [AUTO-TRANSLATED:a72fd2ad] */ bool fromSock(int fd, SockNum::SockType type); @@ -344,14 +413,25 @@ class Socket : public std::enable_shared_from_this, public noncopyable, * 目的是一个socket可以被多个poller对象监听,提高性能或实现Socket归属线程的迁移 * @param other 原始的socket对象 * @return 是否成功 + * Clone from another Socket + * The purpose is to allow a socket to be listened to by multiple poller objects, improving performance or implementing socket migration between threads + * @param other Original socket object + * @return Whether successful + + * [AUTO-TRANSLATED:b3669f71] */ bool cloneSocket(const Socket &other); - ////////////设置事件回调//////////// + ////////////设置事件回调//////////// [AUTO-TRANSLATED:0bfc62ce] + //////////// Set event callbacks //////////// /** * 设置数据接收回调,tcp或udp客户端有效 * @param cb 回调对象 + * Set data receive callback, valid for TCP or UDP clients + * @param cb Callback object + + * [AUTO-TRANSLATED:d3f7ae8a] */ void setOnRead(onReadCB cb); void setOnMultiRead(onMultiReadCB cb); @@ -359,12 +439,20 @@ class Socket : public std::enable_shared_from_this, public noncopyable, /** * 设置异常事件(包括eof等)回调 * @param cb 回调对象 + * Set exception event (including EOF) callback + * @param cb Callback object + + * [AUTO-TRANSLATED:ffbea52f] */ void setOnErr(onErrCB cb); /** * 设置tcp监听接收到连接回调 * @param cb 回调对象 + * Set TCP listening receive connection callback + * @param cb Callback object + + * [AUTO-TRANSLATED:cdcfdb9c] */ void setOnAccept(onAcceptCB cb); @@ -372,22 +460,36 @@ class Socket : public std::enable_shared_from_this, public noncopyable, * 设置socket写缓存清空事件回调 * 通过该回调可以实现发送流控 * @param cb 回调对象 + * Set socket write buffer clear event callback + * This callback can be used to implement send flow control + * @param cb Callback object + + * [AUTO-TRANSLATED:a5ef862d] */ void setOnFlush(onFlush cb); /** * 设置accept时,socket构造事件回调 * @param cb 回调 + * Set accept callback when socket is constructed + * @param cb callback + + * [AUTO-TRANSLATED:d946409b] */ void setOnBeforeAccept(onCreateSocket cb); /** * 设置发送buffer结果回调 * @param cb 回调 + * Set send buffer result callback + * @param cb callback + + * [AUTO-TRANSLATED:1edb77bb] */ void setOnSendResult(onSendResult cb); - ////////////发送数据相关接口//////////// + ////////////发送数据相关接口//////////// [AUTO-TRANSLATED:c14ca1a7] + ////////////Data sending related interfaces//////////// /** * 发送数据指针 @@ -397,23 +499,43 @@ class Socket : public std::enable_shared_from_this, public noncopyable, * @param addr_len 目标地址长度 * @param try_flush 是否尝试写socket * @return -1代表失败(socket无效),0代表数据长度为0,否则返回数据长度 + * Send data pointer + * @param buf data pointer + * @param size data length + * @param addr target address + * @param addr_len target address length + * @param try_flush whether to try writing to the socket + * @return -1 represents failure (invalid socket), 0 represents data length is 0, otherwise returns data length + + * [AUTO-TRANSLATED:718d6192] */ ssize_t send(const char *buf, size_t size = 0, struct sockaddr *addr = nullptr, socklen_t addr_len = 0, bool try_flush = true); /** * 发送string + * Send string + + * [AUTO-TRANSLATED:f9dfdfcf] */ ssize_t send(std::string buf, struct sockaddr *addr = nullptr, socklen_t addr_len = 0, bool try_flush = true); /** * 发送Buffer对象,Socket对象发送数据的统一出口 * socket对象发送数据的统一出口 + * Send Buffer object, unified exit for Socket object to send data + * unified exit for Socket object to send data + + * [AUTO-TRANSLATED:5e69facd] */ ssize_t send(Buffer::Ptr buf, struct sockaddr *addr = nullptr, socklen_t addr_len = 0, bool try_flush = true); /** * 尝试将所有数据写socket * @return -1代表失败(socket无效或者发送超时),0代表成功? + * Try to write all data to the socket + * @return -1 represents failure (invalid socket or send timeout), 0 represents success? + + * [AUTO-TRANSLATED:8e975c68] */ int flushAll(); @@ -421,47 +543,79 @@ class Socket : public std::enable_shared_from_this, public noncopyable, * 关闭socket且触发onErr回调,onErr回调将在poller线程中进行 * @param err 错误原因 * @return 是否成功触发onErr回调 + * Close the socket and trigger the onErr callback, the onErr callback will be executed in the poller thread + * @param err error reason + * @return whether the onErr callback is successfully triggered + + * [AUTO-TRANSLATED:366db327] */ bool emitErr(const SockException &err) noexcept; /** * 关闭或开启数据接收 * @param enabled 是否开启 + * Enable or disable data reception + * @param enabled whether to enable + + * [AUTO-TRANSLATED:95cdec39] */ void enableRecv(bool enabled); /** * 获取裸文件描述符,请勿进行close操作(因为Socket对象会管理其生命周期) * @return 文件描述符 + * Get the raw file descriptor, do not perform close operation (because the Socket object will manage its lifecycle) + * @return file descriptor + + * [AUTO-TRANSLATED:75417922] */ int rawFD() const; /** * tcp客户端是否处于连接状态 * 支持Sock_TCP类型socket + * Whether the TCP client is in a connected state + * Supports Sock_TCP type socket + + * [AUTO-TRANSLATED:42c0c094] */ bool alive() const; /** * 返回socket类型 + * Returns the socket type + + * [AUTO-TRANSLATED:2009a5d2] */ SockNum::SockType sockType() const; /** * 设置发送超时主动断开时间;默认10秒 * @param second 发送超时数据,单位秒 + * Sets the send timeout to disconnect actively; default 10 seconds + * @param second Send timeout data, in seconds + + * [AUTO-TRANSLATED:49127ce8] */ void setSendTimeOutSecond(uint32_t second); /** * 套接字是否忙,如果套接字写缓存已满则返回true * @return 套接字是否忙 + * Whether the socket is busy, if the socket write buffer is full, returns true + * @return Whether the socket is busy + + * [AUTO-TRANSLATED:4b753c62] */ bool isSocketBusy() const; /** * 获取poller线程对象 * @return poller线程对象 + * Gets the poller thread object + * @return poller thread object + + * [AUTO-TRANSLATED:cfc5d2c4] */ const EventPoller::Ptr &getPoller() const; @@ -471,38 +625,65 @@ class Socket : public std::enable_shared_from_this, public noncopyable, * @param addr_len 目标地址长度 * @param soft_bind 是否软绑定,软绑定时不调用udp connect接口,只保存目标地址信息,发送时再传递到sendto函数 * @return 是否成功 + * Binds the UDP target address, subsequent sends do not need to specify it separately + * @param dst_addr Target address + * @param addr_len Target address length + * @param soft_bind Whether to soft bind, soft binding does not call the UDP connect interface, only saves the target address information, and sends it to the sendto function + * @return Whether successful + + * [AUTO-TRANSLATED:946bfe2a] */ bool bindPeerAddr(const struct sockaddr *dst_addr, socklen_t addr_len = 0, bool soft_bind = false); /** * 设置发送flags * @param flags 发送的flag + * Sets the send flags + * @param flags Send flags + + * [AUTO-TRANSLATED:2b11445c] */ void setSendFlags(int flags = SOCKET_DEFAULE_FLAGS); /** * 关闭套接字 * @param close_fd 是否关闭fd还是只移除io事件监听 + * Closes the socket + * @param close_fd Whether to close the fd or only remove the IO event listener + + * [AUTO-TRANSLATED:db624fc6] */ void closeSock(bool close_fd = true); /** * 获取发送缓存包个数(不是字节数) + * Gets the number of packets in the send buffer (not the number of bytes) + + * [AUTO-TRANSLATED:2f853b18] */ size_t getSendBufferCount(); /** * 获取上次socket发送缓存清空至今的毫秒数,单位毫秒 + * Gets the number of milliseconds since the last socket send buffer was cleared, in milliseconds + + * [AUTO-TRANSLATED:567c2818] */ uint64_t elapsedTimeAfterFlushed(); /** * 获取接收速率,单位bytes/s + * Get the receiving rate, in bytes/s + + * [AUTO-TRANSLATED:5de8aa1c] */ int getRecvSpeed(); /** * 获取发送速率,单位bytes/s + * Get the sending rate, in bytes/s + + * [AUTO-TRANSLATED:96a2595d] */ int getSendSpeed(); @@ -531,67 +712,95 @@ class Socket : public std::enable_shared_from_this, public noncopyable, bool fromSock_l(SockNum::Ptr sock); private: - // send socket时的flag + // send socket时的flag [AUTO-TRANSLATED:e364a1bf] + //Flag for sending socket int _sock_flags = SOCKET_DEFAULE_FLAGS; - // 最大发送缓存,单位毫秒,距上次发送缓存清空时间不能超过该参数 + // 最大发送缓存,单位毫秒,距上次发送缓存清空时间不能超过该参数 [AUTO-TRANSLATED:3bd6dba3] + //Maximum send buffer, in milliseconds, the time since the last send buffer was cleared cannot exceed this parameter uint32_t _max_send_buffer_ms = SEND_TIME_OUT_SEC * 1000; - // 控制是否接收监听socket可读事件,关闭后可用于流量控制 + // 控制是否接收监听socket可读事件,关闭后可用于流量控制 [AUTO-TRANSLATED:71de6ece] + //Control whether to receive listen socket readable events, can be used for traffic control after closing std::atomic _enable_recv { true }; - // 标记该socket是否可写,socket写缓存满了就不可写 + // 标记该socket是否可写,socket写缓存满了就不可写 [AUTO-TRANSLATED:32392de2] + //Mark whether the socket is writable, the socket write buffer is full and cannot be written std::atomic _sendable { true }; - // 是否已经触发err回调了 + // 是否已经触发err回调了 [AUTO-TRANSLATED:17ab8384] + //Whether the err callback has been triggered bool _err_emit = false; - // 是否启用网速统计 + // 是否启用网速统计 [AUTO-TRANSLATED:c0c0e8ee] + //Whether to enable network speed statistics bool _enable_speed = false; - // udp发送目标地址 + // udp发送目标地址 [AUTO-TRANSLATED:cce2315a] + //UDP send target address std::shared_ptr _udp_send_dst; - // 接收速率统计 + // 接收速率统计 [AUTO-TRANSLATED:20dcd724] + //Receiving rate statistics BytesSpeed _recv_speed; - // 发送速率统计 + // 发送速率统计 [AUTO-TRANSLATED:eab3486a] + //Send rate statistics BytesSpeed _send_speed; - // tcp连接超时定时器 + // tcp连接超时定时器 [AUTO-TRANSLATED:1b3e5fc4] + //TCP connection timeout timer Timer::Ptr _con_timer; - // tcp连接结果回调对象 + // tcp连接结果回调对象 [AUTO-TRANSLATED:4f1c366a] + //TCP connection result callback object std::shared_ptr _async_con_cb; - // 记录上次发送缓存(包括socket写缓存、应用层缓存)清空的计时器 + // 记录上次发送缓存(包括socket写缓存、应用层缓存)清空的计时器 [AUTO-TRANSLATED:2c44d156] + //Record the timer for the last send buffer (including socket write buffer and application layer buffer) cleared Ticker _send_flush_ticker; - // socket fd的抽象类 + // socket fd的抽象类 [AUTO-TRANSLATED:31e4ea33] + //Abstract class for socket fd SockFD::Ptr _sock_fd; - // 本socket绑定的poller线程,事件触发于此线程 + // 本socket绑定的poller线程,事件触发于此线程 [AUTO-TRANSLATED:6f782513] + //The poller thread bound to this socket, events are triggered in this thread EventPoller::Ptr _poller; - // 跨线程访问_sock_fd时需要上锁 + // 跨线程访问_sock_fd时需要上锁 [AUTO-TRANSLATED:dc63f6c4] + //Need to lock when accessing _sock_fd across threads mutable MutexWrapper _mtx_sock_fd; - // socket异常事件(比如说断开) + // socket异常事件(比如说断开) [AUTO-TRANSLATED:96c028e8] + //Socket exception event (such as disconnection) onErrCB _on_err; - // 收到数据事件 + // 收到数据事件 [AUTO-TRANSLATED:23946f9b] + //Receive data event onMultiReadCB _on_multi_read; - // socket缓存清空事件(可用于发送流速控制) + // socket缓存清空事件(可用于发送流速控制) [AUTO-TRANSLATED:976b84ef] + //Socket buffer cleared event (can be used for send flow control) onFlush _on_flush; - // tcp监听收到accept请求事件 + // tcp监听收到accept请求事件 [AUTO-TRANSLATED:5fe01738] + //TCP listener receives an accept request event onAcceptCB _on_accept; - // tcp监听收到accept请求,自定义创建peer Socket事件(可以控制子Socket绑定到其他poller线程) + // tcp监听收到accept请求,自定义创建peer Socket事件(可以控制子Socket绑定到其他poller线程) [AUTO-TRANSLATED:da85b845] + //TCP listener receives an accept request, custom creation of peer Socket event (can control binding of child Socket to other poller threads) onCreateSocket _on_before_accept; - // 设置上述回调函数的锁 + // 设置上述回调函数的锁 [AUTO-TRANSLATED:302ca377] + //Set the lock for the above callback function MutexWrapper _mtx_event; - // 一级发送缓存, socket可写时,会把一级缓存批量送入到二级缓存 + // 一级发送缓存, socket可写时,会把一级缓存批量送入到二级缓存 [AUTO-TRANSLATED:26f1da58] + //First-level send cache, when the socket is writable, it will batch the first-level cache into the second-level cache List> _send_buf_waiting; - // 一级发送缓存锁 + // 一级发送缓存锁 [AUTO-TRANSLATED:9ec6c6a9] + //First-level send cache lock MutexWrapper _mtx_send_buf_waiting; - // 二级发送缓存, socket可写时,会把二级缓存批量写入到socket + // 二级发送缓存, socket可写时,会把二级缓存批量写入到socket [AUTO-TRANSLATED:cc665665] + //Second-level send cache, when the socket is writable, it will batch the second-level cache into the socket List _send_buf_sending; - // 二级发送缓存锁 + // 二级发送缓存锁 [AUTO-TRANSLATED:306e3472] + //Second-level send cache lock MutexWrapper _mtx_send_buf_sending; - // 发送buffer结果回调 + // 发送buffer结果回调 [AUTO-TRANSLATED:1cac46fd] + //Send buffer result callback BufferList::SendResult _send_result; - // 对象个数统计 + // 对象个数统计 [AUTO-TRANSLATED:f4a012d0] + //Object count statistics ObjectStatistic _statistic; - // 链接缓存地址,防止tcp reset 导致无法获取对端的地址 + // 链接缓存地址,防止tcp reset 导致无法获取对端的地址 [AUTO-TRANSLATED:f8847463] + //Connection cache address, to prevent TCP reset from causing the inability to obtain the peer's address struct sockaddr_storage _local_addr; struct sockaddr_storage _peer_addr; }; @@ -603,14 +812,18 @@ class SockSender { virtual ssize_t send(Buffer::Ptr buf) = 0; virtual void shutdown(const SockException &ex = SockException(Err_shutdown, "self shutdown")) = 0; - //发送char * + //发送char * [AUTO-TRANSLATED:ab84aeb3] + //Send char * SockSender &operator << (const char *buf); - //发送字符串 + //发送字符串 [AUTO-TRANSLATED:3d678d0a] + //Send string SockSender &operator << (std::string buf); - //发送Buffer对象 + //发送Buffer对象 [AUTO-TRANSLATED:8a6fb71c] + //Send Buffer object SockSender &operator << (Buffer::Ptr buf); - //发送其他类型是数据 + //发送其他类型是数据 [AUTO-TRANSLATED:86b0319a] + //Send other types of data template SockSender &operator << (T &&buf) { std::ostringstream ss; @@ -623,7 +836,8 @@ class SockSender { ssize_t send(const char *buf, size_t size = 0); }; -//Socket对象的包装类 +//Socket对象的包装类 [AUTO-TRANSLATED:9d384814] +//Socket object wrapper class class SocketHelper : public SockSender, public SockInfo, public TaskExecutorInterface, public std::enable_shared_from_this { public: using Ptr = std::shared_ptr; @@ -633,50 +847,81 @@ class SocketHelper : public SockSender, public SockInfo, public TaskExecutorInte ///////////////////// Socket util std::functions ///////////////////// /** * 获取poller线程 + * Get poller thread + + * [AUTO-TRANSLATED:bd1ed6dc] */ const EventPoller::Ptr& getPoller() const; /** * 设置批量发送标记,用于提升性能 * @param try_flush 批量发送标记 + * Set batch send flag, used to improve performance + * @param try_flush Batch send flag + + * [AUTO-TRANSLATED:8c3f2ae1] */ void setSendFlushFlag(bool try_flush); /** * 设置socket发送flags * @param flags socket发送flags + * Set socket send flags + * @param flags Socket send flags + + * [AUTO-TRANSLATED:d5d2eec9] */ void setSendFlags(int flags); /** * 套接字是否忙,如果套接字写缓存已满则返回true + * Whether the socket is busy, returns true if the socket write buffer is full + + * [AUTO-TRANSLATED:5c3cc85c] */ bool isSocketBusy() const; /** * 设置Socket创建器,自定义Socket创建方式 * @param cb 创建器 + * Set Socket creator, customize Socket creation method + * @param cb Creator + + * [AUTO-TRANSLATED:df045ccf] */ void setOnCreateSocket(Socket::onCreateSocket cb); /** * 创建socket对象 + * Create a socket object + + * [AUTO-TRANSLATED:260848b5] */ Socket::Ptr createSocket(); /** * 获取socket对象 + * Get the socket object + + * [AUTO-TRANSLATED:f737fb8d] */ const Socket::Ptr &getSock() const; /** * 尝试将所有数据写socket * @return -1代表失败(socket无效或者发送超时),0代表成功? + * Try to write all data to the socket + * @return -1 represents failure (invalid socket or send timeout), 0 represents success + + * [AUTO-TRANSLATED:8e975c68] */ int flushAll(); /** * 是否ssl加密 + * Whether SSL encryption is enabled + + * [AUTO-TRANSLATED:95b748f2] */ virtual bool overSsl() const { return false; } @@ -691,6 +936,11 @@ class SocketHelper : public SockSender, public SockInfo, public TaskExecutorInte * 任务切换到所属poller线程执行 * @param task 任务 * @param may_sync 是否运行同步执行任务 + * Switch the task to the poller thread for execution + * @param task The task to be executed + * @param may_sync Whether to run the task synchronously + + * [AUTO-TRANSLATED:c0a93c6e] */ Task::Ptr async(TaskIn task, bool may_sync = true) override; Task::Ptr async_first(TaskIn task, bool may_sync = true) override; @@ -699,22 +949,35 @@ class SocketHelper : public SockSender, public SockInfo, public TaskExecutorInte /** * 使能 SockSender 其他未被重写的send重载函数 + * Enable other non-overridden send functions in SockSender + + * [AUTO-TRANSLATED:e6baa93a] */ using SockSender::send; /** * 统一发送数据的出口 + * Unified data sending outlet + + * [AUTO-TRANSLATED:6a7a5178] */ ssize_t send(Buffer::Ptr buf) override; /** * 触发onErr事件 + * Trigger the onErr event + + * [AUTO-TRANSLATED:b485450f] */ void shutdown(const SockException &ex = SockException(Err_shutdown, "self shutdown")) override; /** * 线程安全的脱离 Server 并触发 onError 事件 * @param ex 触发 onError 事件的原因 + * Safely detach from the Server and trigger the onError event in a thread-safe manner + * @param ex The reason for triggering the onError event + + * [AUTO-TRANSLATED:739455d5] */ void safeShutdown(const SockException &ex = SockException(Err_shutdown, "self shutdown")); @@ -722,6 +985,10 @@ class SocketHelper : public SockSender, public SockInfo, public TaskExecutorInte /** * 接收数据入口 * @param buf 数据,可以重复使用内存区,不可被缓存使用 + * Data receiving entry point + * @param buf Data buffer, can be reused, and cannot be cached + + * [AUTO-TRANSLATED:9d498f56] */ virtual void onRecv(const Buffer::Ptr &buf) = 0; @@ -729,16 +996,27 @@ class SocketHelper : public SockSender, public SockInfo, public TaskExecutorInte * 收到 eof 或其他导致脱离 Server 事件的回调 * 收到该事件时, 该对象一般将立即被销毁 * @param err 原因 + * Callback received eof or other events that cause disconnection from Server + * When this event is received, the object is generally destroyed immediately + * @param err reason + + * [AUTO-TRANSLATED:a9349e0f] */ virtual void onError(const SockException &err) = 0; /** * 数据全部发送完毕后回调 + * Callback after all data has been sent + + * [AUTO-TRANSLATED:8b2ba800] */ virtual void onFlush() {} /** * 每隔一段时间触发, 用来做超时管理 + * Triggered at regular intervals, used for timeout management + + * [AUTO-TRANSLATED:af9e6c42] */ virtual void onManager() = 0; diff --git a/src/Network/TcpClient.cpp b/src/Network/TcpClient.cpp index b2d292fca..6de5fb740 100644 --- a/src/Network/TcpClient.cpp +++ b/src/Network/TcpClient.cpp @@ -19,7 +19,8 @@ StatisticImp(TcpClient) TcpClient::TcpClient(const EventPoller::Ptr &poller) : SocketHelper(nullptr) { setPoller(poller ? poller : EventPollerPool::Instance().getPoller()); setOnCreateSocket([](const EventPoller::Ptr &poller) { - //TCP客户端默认开启互斥锁 + //TCP客户端默认开启互斥锁 [AUTO-TRANSLATED:94fad9cd] + //TCP client defaults to enabling mutex lock return Socket::createSocket(poller, true); }); } @@ -35,11 +36,14 @@ void TcpClient::shutdown(const SockException &ex) { bool TcpClient::alive() const { if (_timer) { - //连接中或已连接 + //连接中或已连接 [AUTO-TRANSLATED:bf2b744a] + //Connecting or already connected return true; } - //在websocket client(zlmediakit)相关代码中, - //_timer一直为空,但是socket fd有效,alive状态也应该返回true + //在websocket client(zlmediakit)相关代码中, [AUTO-TRANSLATED:d309d587] + //In websocket client (zlmediakit) related code, + //_timer一直为空,但是socket fd有效,alive状态也应该返回true [AUTO-TRANSLATED:344889b8] + //_timer is always empty, but socket fd is valid, and alive status should also return true auto sock = getSock(); return sock && sock->alive(); } @@ -68,7 +72,8 @@ void TcpClient::startConnect(const string &url, uint16_t port, float timeout_sec return; } if (sock_ptr != strong_self->getSock().get()) { - //已经重连socket,上次的socket的事件忽略掉 + //已经重连socket,上次的socket的事件忽略掉 [AUTO-TRANSLATED:9bf35a7a] + //Socket has been reconnected, last socket's event is ignored return; } strong_self->_timer.reset(); @@ -88,7 +93,8 @@ void TcpClient::startConnect(const string &url, uint16_t port, float timeout_sec void TcpClient::onSockConnect(const SockException &ex) { TraceL << getIdentifier() << " connect result: " << ex; if (ex) { - //连接失败 + //连接失败 [AUTO-TRANSLATED:33415985] + //Connection failed _timer.reset(); onConnect(ex); return; @@ -102,7 +108,8 @@ void TcpClient::onSockConnect(const SockException &ex) { return false; } if (sock_ptr != strong_self->getSock().get()) { - //已经重连socket,上传socket的事件忽略掉 + //已经重连socket,上传socket的事件忽略掉 [AUTO-TRANSLATED:243a8c95] + //Socket has been reconnected, upload socket's event is ignored return false; } strong_self->onFlush(); @@ -115,7 +122,8 @@ void TcpClient::onSockConnect(const SockException &ex) { return; } if (sock_ptr != strong_self->getSock().get()) { - //已经重连socket,上传socket的事件忽略掉 + //已经重连socket,上传socket的事件忽略掉 [AUTO-TRANSLATED:243a8c95] + //Socket has been reconnected, upload socket's event is ignored return; } try { diff --git a/src/Network/TcpClient.h b/src/Network/TcpClient.h index f470f4abc..a7fa70836 100644 --- a/src/Network/TcpClient.h +++ b/src/Network/TcpClient.h @@ -17,7 +17,8 @@ namespace toolkit { -//Tcp客户端,Socket对象默认开始互斥锁 +//Tcp客户端,Socket对象默认开始互斥锁 [AUTO-TRANSLATED:5cc9a824] +//Tcp client, Socket object defaults to starting mutex lock class TcpClient : public SocketHelper { public: using Ptr = std::shared_ptr; @@ -30,6 +31,13 @@ class TcpClient : public SocketHelper { * @param port 服务器端口 * @param timeout_sec 超时时间,单位秒 * @param local_port 本地端口 + * Start connecting to the TCP server + * @param url Server IP or domain name + * @param port Server port + * @param timeout_sec Timeout time, in seconds + * @param local_port Local port + + * [AUTO-TRANSLATED:7aa87355] */ virtual void startConnect(const std::string &url, uint16_t port, float timeout_sec = 5, uint16_t local_port = 0); @@ -40,28 +48,50 @@ class TcpClient : public SocketHelper { * @proxy_port 代理端口 * @param timeout_sec 超时时间,单位秒 * @param local_port 本地端口 + * Start connecting to the TCP server through a proxy + * @param url Server IP or domain name + * @proxy_host Proxy IP + * @proxy_port Proxy port + * @param timeout_sec Timeout time, in seconds + * @param local_port Local port + + * [AUTO-TRANSLATED:2739bd58] */ virtual void startConnectWithProxy(const std::string &url, const std::string &proxy_host, uint16_t proxy_port, float timeout_sec = 5, uint16_t local_port = 0){}; /** * 主动断开连接 * @param ex 触发onErr事件时的参数 + * Actively disconnect the connection + * @param ex Parameter when triggering the onErr event + + * [AUTO-TRANSLATED:5f6f3017] */ void shutdown(const SockException &ex = SockException(Err_shutdown, "self shutdown")) override; /** * 连接中或已连接返回true,断开连接时返回false + * Returns true if connected or connecting, returns false if disconnected + + * [AUTO-TRANSLATED:60595edc] */ virtual bool alive() const; /** * 设置网卡适配器,使用该网卡与服务器通信 * @param local_ip 本地网卡ip + * Set the network card adapter, use this network card to communicate with the server + * @param local_ip Local network card IP + + * [AUTO-TRANSLATED:2549c18d] */ virtual void setNetAdapter(const std::string &local_ip); /** * 唯一标识 + * Unique identifier + + * [AUTO-TRANSLATED:6b21021f] */ std::string getIdentifier() const override; @@ -69,11 +99,18 @@ class TcpClient : public SocketHelper { /** * 连接服务器结果回调 * @param ex 成功与否 + * Connection result callback + * @param ex Success or failure + + * [AUTO-TRANSLATED:103bb2cb] */ virtual void onConnect(const SockException &ex) = 0; /** * tcp连接成功后每2秒触发一次该事件 + * Trigger this event every 2 seconds after a successful TCP connection + + * [AUTO-TRANSLATED:37b40b5d] */ void onManager() override {} @@ -84,11 +121,13 @@ class TcpClient : public SocketHelper { mutable std::string _id; std::string _net_adapter = "::"; std::shared_ptr _timer; - //对象个数统计 + //对象个数统计 [AUTO-TRANSLATED:3b43e8c2] + //Object count statistics ObjectStatistic _statistic; }; -//用于实现TLS客户端的模板对象 +//用于实现TLS客户端的模板对象 [AUTO-TRANSLATED:e4d399a3] +//Template object for implementing TLS client template class TcpClientWithSSL : public TcpClientType { public: @@ -111,7 +150,8 @@ class TcpClientWithSSL : public TcpClientType { } } - // 使能其他未被重写的send函数 + // 使能其他未被重写的send函数 [AUTO-TRANSLATED:5f01f91b] + //Enable other unoverridden send functions using TcpClientType::send; ssize_t send(Buffer::Ptr buf) override { @@ -123,7 +163,8 @@ class TcpClientWithSSL : public TcpClientType { return TcpClientType::send(std::move(buf)); } - //添加public_onRecv和public_send函数是解决较低版本gcc一个lambad中不能访问protected或private方法的bug + //添加public_onRecv和public_send函数是解决较低版本gcc一个lambad中不能访问protected或private方法的bug [AUTO-TRANSLATED:210f092e] + //Adding public_onRecv and public_send functions is to solve a bug in lower version gcc where a lambda cannot access protected or private methods inline void public_onRecv(const Buffer::Ptr &buf) { TcpClientType::onRecv(buf); } @@ -155,7 +196,8 @@ class TcpClientWithSSL : public TcpClientType { }); if (!isIP(_host.data())) { - //设置ssl域名 + //设置ssl域名 [AUTO-TRANSLATED:1286a860] + //Set ssl domain _ssl_box->setHost(_host.data()); } } @@ -163,6 +205,9 @@ class TcpClientWithSSL : public TcpClientType { } /** * 重置ssl, 主要为了解决一些302跳转时http与https的转换 + * Reset ssl, mainly to solve some 302 redirects when switching between http and https + + * [AUTO-TRANSLATED:12ad26da] */ void setDoNotUseSSL() { _ssl_box.reset(); diff --git a/src/Network/TcpServer.cpp b/src/Network/TcpServer.cpp index 3d9147438..34312e9b6 100644 --- a/src/Network/TcpServer.cpp +++ b/src/Network/TcpServer.cpp @@ -38,7 +38,8 @@ void TcpServer::setupEvent() { auto ptr = sock->getPoller().get(); auto server = strong_self->getServer(ptr); ptr->async([server, sock, complete]() { - //该tcp客户端派发给对应线程的TcpServer服务器 + //该tcp客户端派发给对应线程的TcpServer服务器 [AUTO-TRANSLATED:662b882f] + //This TCP client is dispatched to the corresponding thread of the TcpServer server server->onAcceptConnection(sock); }); } @@ -50,7 +51,8 @@ TcpServer::~TcpServer() { InfoL << "Close tcp server [" << _socket->get_local_ip() << "]: " << _socket->get_local_port(); } _timer.reset(); - //先关闭socket监听,防止收到新的连接 + //先关闭socket监听,防止收到新的连接 [AUTO-TRANSLATED:cd65064f] + //First close the socket listening to prevent receiving new connections _socket.reset(); _session_map.clear(); _cloned_server.clear(); @@ -82,7 +84,8 @@ TcpServer::Ptr TcpServer::onCreatServer(const EventPoller::Ptr &poller) { Socket::Ptr TcpServer::onBeforeAcceptConnection(const EventPoller::Ptr &poller) { assert(_poller->isCurrentThread()); - //此处改成自定义获取poller对象,防止负载不均衡 + //此处改成自定义获取poller对象,防止负载不均衡 [AUTO-TRANSLATED:16c66457] + //Modify this to a custom way of getting the poller object to prevent load imbalance return createSocket(_multi_poller ? EventPollerPool::Instance().getPoller(false) : _poller); } @@ -107,24 +110,30 @@ void TcpServer::cloneFrom(const TcpServer &that) { _parent = static_pointer_cast(const_cast(that).shared_from_this()); } -// 接收到客户端连接请求 +// 接收到客户端连接请求 [AUTO-TRANSLATED:8a67b72a] +//Received a client connection request Session::Ptr TcpServer::onAcceptConnection(const Socket::Ptr &sock) { assert(_poller->isCurrentThread()); weak_ptr weak_self = std::static_pointer_cast(shared_from_this()); - //创建一个Session;这里实现创建不同的服务会话实例 + //创建一个Session;这里实现创建不同的服务会话实例 [AUTO-TRANSLATED:9ed745be] + //Create a Session; here implement creating different service session instances auto helper = _session_alloc(std::static_pointer_cast(shared_from_this()), sock); auto session = helper->session(); - //把本服务器的配置传递给Session + //把本服务器的配置传递给Session [AUTO-TRANSLATED:e3711484] + //Pass the configuration of this server to the Session session->attachServer(*this); - //_session_map::emplace肯定能成功 + //_session_map::emplace肯定能成功 [AUTO-TRANSLATED:09d4aef7] + //_session_map::emplace will definitely succeed auto success = _session_map.emplace(helper.get(), helper).second; assert(success == true); weak_ptr weak_session = session; - //会话接收数据事件 + //会话接收数据事件 [AUTO-TRANSLATED:f3f4cbbb] + //Session receives data event sock->setOnRead([weak_session](const Buffer::Ptr &buf, struct sockaddr *, int) { - //获取会话强应用 + //获取会话强应用 [AUTO-TRANSLATED:187497e6] + //Get the strong application of the session auto strong_session = weak_session.lock(); if (!strong_session) { return; @@ -140,13 +149,18 @@ Session::Ptr TcpServer::onAcceptConnection(const Socket::Ptr &sock) { SessionHelper *ptr = helper.get(); auto cls = ptr->className(); - //会话接收到错误事件 + //会话接收到错误事件 [AUTO-TRANSLATED:b000e868] + //Session receives an error event sock->setOnErr([weak_self, weak_session, ptr, cls](const SockException &err) { - //在本函数作用域结束时移除会话对象 - //目的是确保移除会话前执行其onError函数 - //同时避免其onError函数抛异常时没有移除会话对象 + //在本函数作用域结束时移除会话对象 [AUTO-TRANSLATED:5c4433b8] + //Remove the session object when the function scope ends + //目的是确保移除会话前执行其onError函数 [AUTO-TRANSLATED:1e6c65df] + //The purpose is to ensure that the onError function is executed before removing the session + //同时避免其onError函数抛异常时没有移除会话对象 [AUTO-TRANSLATED:6d541cbd] + //And avoid not removing the session object when the onError function throws an exception onceToken token(nullptr, [&]() { - //移除掉会话 + //移除掉会话 [AUTO-TRANSLATED:e7c27790] + //Remove the session auto strong_self = weak_self.lock(); if (!strong_self) { return; @@ -154,10 +168,12 @@ Session::Ptr TcpServer::onAcceptConnection(const Socket::Ptr &sock) { assert(strong_self->_poller->isCurrentThread()); if (!strong_self->_is_on_manager) { - //该事件不是onManager时触发的,直接操作map + //该事件不是onManager时触发的,直接操作map [AUTO-TRANSLATED:d90ee039] + //This event is not triggered by onManager, directly operate on the map strong_self->_session_map.erase(ptr); } else { - //遍历map时不能直接删除元素 + //遍历map时不能直接删除元素 [AUTO-TRANSLATED:0f00040c] + //Cannot directly delete elements when traversing the map strong_self->_poller->async([weak_self, ptr]() { auto strong_self = weak_self.lock(); if (strong_self) { @@ -167,10 +183,12 @@ Session::Ptr TcpServer::onAcceptConnection(const Socket::Ptr &sock) { } }); - //获取会话强应用 + //获取会话强应用 [AUTO-TRANSLATED:187497e6] + //Get the strong reference of the session auto strong_session = weak_session.lock(); if (strong_session) { - //触发onError事件回调 + //触发onError事件回调 [AUTO-TRANSLATED:825d16df] + //Trigger the onError event callback TraceP(strong_session) << cls << " on err: " << err; strong_session->onError(err); } @@ -181,7 +199,8 @@ Session::Ptr TcpServer::onAcceptConnection(const Socket::Ptr &sock) { void TcpServer::start_l(uint16_t port, const std::string &host, uint32_t backlog) { setupEvent(); - //新建一个定时器定时管理这些tcp会话 + //新建一个定时器定时管理这些tcp会话 [AUTO-TRANSLATED:ef859bd7] + //Create a new timer to manage these TCP sessions periodically weak_ptr weak_self = std::static_pointer_cast(shared_from_this()); _timer = std::make_shared(2.0f, [weak_self]() -> bool { auto strong_self = weak_self.lock(); @@ -209,12 +228,14 @@ void TcpServer::start_l(uint16_t port, const std::string &host, uint32_t backlog } if (!_socket->listen(port, host.c_str(), backlog)) { - // 创建tcp监听失败,可能是由于端口占用或权限问题 + // 创建tcp监听失败,可能是由于端口占用或权限问题 [AUTO-TRANSLATED:88ebdefc] + //TCP listener creation failed, possibly due to port occupation or permission issues string err = (StrPrinter << "Listen on " << host << " " << port << " failed: " << get_uv_errmsg(true)); throw std::runtime_error(err); } for (auto &pr: _cloned_server) { - // 启动子Server + // 启动子Server [AUTO-TRANSLATED:1820131c] + //Start the child Server pr.second->_socket->cloneSocket(*_socket); } @@ -231,7 +252,8 @@ void TcpServer::onManagerSession() { }); for (auto &pr : _session_map) { - //遍历时,可能触发onErr事件(也会操作_session_map) + //遍历时,可能触发onErr事件(也会操作_session_map) [AUTO-TRANSLATED:7760b80d] + //When traversing, the onErr event may be triggered (also operates on _session_map) try { pr.second->session()->onManager(); } catch (exception &ex) { @@ -249,10 +271,12 @@ TcpServer::Ptr TcpServer::getServer(const EventPoller *poller) const { auto &ref = parent ? parent->_cloned_server : _cloned_server; auto it = ref.find(poller); if (it != ref.end()) { - //派发到cloned server + //派发到cloned server [AUTO-TRANSLATED:8765ab56] + //Dispatch to the cloned server return it->second; } - //派发到parent server + //派发到parent server [AUTO-TRANSLATED:4cf34169] + //Dispatch to the parent server return static_pointer_cast(parent ? parent : const_cast(this)->shared_from_this()); } diff --git a/src/Network/TcpServer.h b/src/Network/TcpServer.h index 11d0d8942..344653c19 100644 --- a/src/Network/TcpServer.h +++ b/src/Network/TcpServer.h @@ -21,7 +21,8 @@ namespace toolkit { -//TCP服务器,可配置的;配置通过Session::attachServer方法传递给会话对象 +//TCP服务器,可配置的;配置通过Session::attachServer方法传递给会话对象 [AUTO-TRANSLATED:4e55c332] +//Configurable TCP server; configuration is passed to the session object through the Session::attachServer method class TcpServer : public Server { public: using Ptr = std::shared_ptr; @@ -32,6 +33,13 @@ class TcpServer : public Server { * 这些子TcpServer对象通过Socket对象克隆的方式在多个poller线程中监听同一个listen fd * 这样这个TCP服务器将会通过抢占式accept的方式把客户端均匀的分布到不同的poller线程 * 通过该方式能实现客户端负载均衡以及提高连接接收速度 + * Creates a TCP server, the accept event of the listen fd will be added to all poller threads for listening + * When calling the TcpServer::start function, multiple child TcpServer objects will be created internally, + * These child TcpServer objects will be cloned through the Socket object in multiple poller threads to listen to the same listen fd + * This way, the TCP server will distribute clients evenly across different poller threads through a preemptive accept approach + * This approach can achieve client load balancing and improve connection acceptance speed + + * [AUTO-TRANSLATED:761a6b1e] */ explicit TcpServer(const EventPoller::Ptr &poller = nullptr); ~TcpServer() override; @@ -41,11 +49,18 @@ class TcpServer : public Server { * @param port 本机端口,0则随机 * @param host 监听网卡ip * @param backlog tcp listen backlog + * @brief Starts the TCP server + * @param port Local port, 0 for random + * @param host Listening network card IP + * @param backlog TCP listen backlog + + * [AUTO-TRANSLATED:9bab69b6] */ template void start(uint16_t port, const std::string &host = "::", uint32_t backlog = 1024, const std::function &)> &cb = nullptr) { static std::string cls_name = toolkit::demangle(typeid(SessionType).name()); - // Session创建器,通过它创建不同类型的服务器 + // Session创建器,通过它创建不同类型的服务器 [AUTO-TRANSLATED:f5585e1e] + //Session creator, creates different types of servers through it _session_alloc = [cb](const TcpServer::Ptr &server, const Socket::Ptr &sock) { auto session = std::shared_ptr(new SessionType(sock), [](SessionType *ptr) { TraceP(static_cast(ptr)) << "~" << cls_name; @@ -63,17 +78,27 @@ class TcpServer : public Server { /** * @brief 获取服务器监听端口号, 服务器可以选择监听随机端口 + * @brief Gets the server listening port number, the server can choose to listen on a random port + + * [AUTO-TRANSLATED:125ff8d8] */ uint16_t getPort(); /** * @brief 自定义socket构建行为 + * @brief Custom socket construction behavior + + * [AUTO-TRANSLATED:4cf98e86] */ void setOnCreateSocket(Socket::onCreateSocket cb); /** * 根据socket对象创建Session对象 * 需要确保在socket归属poller线程执行本函数 + * Creates a Session object based on the socket object + * Ensures that this function is executed in the poller thread that owns the socket + + * [AUTO-TRANSLATED:1d52d9ee] */ Session::Ptr createSession(const Socket::Ptr &socket); @@ -102,7 +127,8 @@ class TcpServer : public Server { std::unordered_map _session_map; std::function _session_alloc; std::unordered_map _cloned_server; - //对象个数统计 + //对象个数统计 [AUTO-TRANSLATED:3b43e8c2] + //Object count statistics ObjectStatistic _statistic; }; diff --git a/src/Network/UdpServer.cpp b/src/Network/UdpServer.cpp index a8fbd468a..07fdf26fe 100644 --- a/src/Network/UdpServer.cpp +++ b/src/Network/UdpServer.cpp @@ -28,7 +28,8 @@ static UdpServer::PeerIdType makeSockId(sockaddr *addr, int) { ret.resize(18); ret[0] = ((struct sockaddr_in *) addr)->sin_port >> 8; ret[1] = ((struct sockaddr_in *) addr)->sin_port & 0xFF; - //ipv4地址统一转换为ipv6方式处理 + //ipv4地址统一转换为ipv6方式处理 [AUTO-TRANSLATED:ad7cf8c3] + //Convert ipv4 addresses to ipv6 for unified processing memcpy(&ret[2], &s_in6_addr_maped, 12); memcpy(&ret[14], &(((struct sockaddr_in *) addr)->sin_addr), 4); return ret; @@ -74,11 +75,13 @@ UdpServer::~UdpServer() { void UdpServer::start_l(uint16_t port, const std::string &host) { setupEvent(); - //主server才创建session map,其他cloned server共享之 + //主server才创建session map,其他cloned server共享之 [AUTO-TRANSLATED:113cf4fd] + //Only the main server creates a session map, other cloned servers share it _session_mutex = std::make_shared(); _session_map = std::make_shared >(); - // 新建一个定时器定时管理这些 udp 会话,这些对象只由主server做超时管理,cloned server不管理 + // 新建一个定时器定时管理这些 udp 会话,这些对象只由主server做超时管理,cloned server不管理 [AUTO-TRANSLATED:d20478a2] + //Create a timer to manage these udp sessions periodically, these objects are only managed by the main server, cloned servers do not manage them std::weak_ptr weak_self = std::static_pointer_cast(shared_from_this()); _timer = std::make_shared(2.0f, [weak_self]() -> bool { if (auto strong_self = weak_self.lock()) { @@ -89,7 +92,8 @@ void UdpServer::start_l(uint16_t port, const std::string &host) { }, _poller); if (_multi_poller) { - // clone server至不同线程,让udp server支持多线程 + // clone server至不同线程,让udp server支持多线程 [AUTO-TRANSLATED:15a85c8f] + //Clone the server to different threads to support multi-threading for the udp server EventPollerPool::Instance().for_each([&](const TaskExecutor::Ptr &executor) { auto poller = std::static_pointer_cast(executor); if (poller == _poller) { @@ -106,17 +110,20 @@ void UdpServer::start_l(uint16_t port, const std::string &host) { } if (!_socket->bindUdpSock(port, host.c_str())) { - // udp 绑定端口失败, 可能是由于端口占用或权限问题 + // udp 绑定端口失败, 可能是由于端口占用或权限问题 [AUTO-TRANSLATED:c31eedba] + //Failed to bind udp port, possibly due to port occupation or permission issues std::string err = (StrPrinter << "Bind udp socket on " << host << " " << port << " failed: " << get_uv_errmsg(true)); throw std::runtime_error(err); } for (auto &pr: _cloned_server) { - // 启动子Server + // 启动子Server [AUTO-TRANSLATED:1820131c] + //Start the child server #if 0 pr.second->_socket->cloneSocket(*_socket); #else - // 实验发现cloneSocket方式虽然可以节省fd资源,但是在某些系统上线程漂移问题更严重 + // 实验发现cloneSocket方式虽然可以节省fd资源,但是在某些系统上线程漂移问题更严重 [AUTO-TRANSLATED:d6a88e17] + //Experiments have found that the cloneSocket method can save fd resources, but the thread drift problem is more serious on some systems pr.second->_socket->bindUdpSock(_socket->get_local_port(), _socket->get_local_ip()); #endif } @@ -149,7 +156,8 @@ void UdpServer::onRead(Buffer::Ptr &buf, sockaddr *addr, int addr_len) { static void emitSessionRecv(const SessionHelper::Ptr &helper, const Buffer::Ptr &buf) { if (!helper->enable) { - // 延时销毁中 + // 延时销毁中 [AUTO-TRANSLATED:24d3d333] + //Delayed destruction in progress return; } try { @@ -162,17 +170,21 @@ static void emitSessionRecv(const SessionHelper::Ptr &helper, const Buffer::Ptr } void UdpServer::onRead_l(bool is_server_fd, const UdpServer::PeerIdType &id, Buffer::Ptr &buf, sockaddr *addr, int addr_len) { - // udp server fd收到数据时触发此函数;大部分情况下数据应该在peer fd触发,此函数应该不是热点函数 + // udp server fd收到数据时触发此函数;大部分情况下数据应该在peer fd触发,此函数应该不是热点函数 [AUTO-TRANSLATED:f347ff20] + //This function is triggered when the udp server fd receives data; in most cases, the data should be triggered by the peer fd, and this function should not be a hot spot bool is_new = false; if (auto helper = getOrCreateSession(id, buf, addr, addr_len, is_new)) { if (helper->session()->getPoller()->isCurrentThread()) { - //当前线程收到数据,直接处理数据 + //当前线程收到数据,直接处理数据 [AUTO-TRANSLATED:07e5a596] + //The current thread receives data and processes it directly emitSessionRecv(helper, buf); } else { - //数据漂移到其他线程,需要先切换线程 + //数据漂移到其他线程,需要先切换线程 [AUTO-TRANSLATED:15235f6f] + //Data migration to another thread requires switching threads first WarnL << "UDP packet incoming from other thread"; std::weak_ptr weak_helper = helper; - //由于socket读buffer是该线程上所有socket共享复用的,所以不能跨线程使用,必须先转移走 + //由于socket读buffer是该线程上所有socket共享复用的,所以不能跨线程使用,必须先转移走 [AUTO-TRANSLATED:1134538b] + //Since the socket read buffer is shared and reused by all sockets on this thread, it cannot be used across threads and must be transferred first auto cacheable_buf = std::move(buf); helper->session()->async([weak_helper, cacheable_buf]() { if (auto strong_helper = weak_helper.lock()) { @@ -193,18 +205,21 @@ void UdpServer::onManagerSession() { decltype(_session_map) copy_map; { std::lock_guard lock(*_session_mutex); - //拷贝map,防止遍历时移除对象 + //拷贝map,防止遍历时移除对象 [AUTO-TRANSLATED:ebbc7595] + //Copy the map to prevent objects from being removed during traversal copy_map = std::make_shared >(*_session_map); } auto lam = [copy_map]() { for (auto &pr : *copy_map) { auto &session = pr.second->session(); if (!session->getPoller()->isCurrentThread()) { - // 该session不归属该poller管理 + // 该session不归属该poller管理 [AUTO-TRANSLATED:d5edb552] + //This session does not belong to the management of this poller continue; } try { - // UDP 会话需要处理超时 + // UDP 会话需要处理超时 [AUTO-TRANSLATED:0a51f8a1] + //UDP sessions need to handle timeouts session->onManager(); } catch (exception &ex) { WarnL << "Exception occurred when emit onManager: " << ex.what(); @@ -222,7 +237,8 @@ void UdpServer::onManagerSession() { SessionHelper::Ptr UdpServer::getOrCreateSession(const UdpServer::PeerIdType &id, Buffer::Ptr &buf, sockaddr *addr, int addr_len, bool &is_new) { { - //减小临界区 + //减小临界区 [AUTO-TRANSLATED:3d6089d8] + //Reduce the critical section std::lock_guard lock(*_session_mutex); auto it = _session_map->find(id); if (it != _session_map->end()) { @@ -234,10 +250,12 @@ SessionHelper::Ptr UdpServer::getOrCreateSession(const UdpServer::PeerIdType &id } SessionHelper::Ptr UdpServer::createSession(const PeerIdType &id, Buffer::Ptr &buf, struct sockaddr *addr, int addr_len) { - // 此处改成自定义获取poller对象,防止负载不均衡 + // 此处改成自定义获取poller对象,防止负载不均衡 [AUTO-TRANSLATED:194e8460] + //Change to custom acquisition of poller objects to prevent load imbalance auto socket = createSocket(_multi_poller ? EventPollerPool::Instance().getPoller(false) : _poller, buf, addr, addr_len); if (!socket) { - //创建socket失败,本次onRead事件收到的数据直接丢弃 + //创建socket失败,本次onRead事件收到的数据直接丢弃 [AUTO-TRANSLATED:b218d68c] + //Socket creation failed, the data received by this onRead event is discarded return nullptr; } @@ -249,7 +267,8 @@ SessionHelper::Ptr UdpServer::createSession(const PeerIdType &id, Buffer::Ptr &b return nullptr; } - //如果已经创建该客户端对应的UdpSession类,那么直接返回 + //如果已经创建该客户端对应的UdpSession类,那么直接返回 [AUTO-TRANSLATED:c57a0d71] + //If the UdpSession class corresponding to this client has already been created, return directly lock_guard lck(*_session_mutex); auto it = _session_map->find(id); if (it != _session_map->end()) { @@ -261,7 +280,8 @@ SessionHelper::Ptr UdpServer::createSession(const PeerIdType &id, Buffer::Ptr &b socket->bindPeerAddr((struct sockaddr *) addr_str.data(), addr_str.size()); auto helper = _session_alloc(server, socket); - // 把本服务器的配置传递给 Session + // 把本服务器的配置传递给 Session [AUTO-TRANSLATED:e3ed95ab] + //Pass the configuration of this server to the Session helper->session()->attachServer(*this); std::weak_ptr weak_helper = helper; @@ -271,7 +291,8 @@ SessionHelper::Ptr UdpServer::createSession(const PeerIdType &id, Buffer::Ptr &b return; } - //快速判断是否为本会话的的数据, 通常应该成立 + //快速判断是否为本会话的的数据, 通常应该成立 [AUTO-TRANSLATED:d5d147e4] + //Quickly determine if it's data for the current session, usually should be true if (id == makeSockId(addr, addr_len)) { if (auto strong_helper = weak_helper.lock()) { emitSessionRecv(strong_helper, buf); @@ -279,23 +300,30 @@ SessionHelper::Ptr UdpServer::createSession(const PeerIdType &id, Buffer::Ptr &b return; } - //收到非本peer fd的数据,让server去派发此数据到合适的session对象 + //收到非本peer fd的数据,让server去派发此数据到合适的session对象 [AUTO-TRANSLATED:e5f44445] + //Received data from a non-current peer fd, let the server dispatch this data to the appropriate session object strong_self->onRead_l(false, id, buf, addr, addr_len); }); socket->setOnErr([weak_self, weak_helper, id](const SockException &err) { - // 在本函数作用域结束时移除会话对象 - // 目的是确保移除会话前执行其 onError 函数 - // 同时避免其 onError 函数抛异常时没有移除会话对象 + // 在本函数作用域结束时移除会话对象 [AUTO-TRANSLATED:b2ade305] + //Remove the session object when this function scope ends + // 目的是确保移除会话前执行其 onError 函数 [AUTO-TRANSLATED:7d0329d7] + //The purpose is to ensure the onError function is executed before removing the session + // 同时避免其 onError 函数抛异常时没有移除会话对象 [AUTO-TRANSLATED:354191bd] + //And avoid not removing the session object when its onError function throws an exception onceToken token(nullptr, [&]() { - // 移除掉会话 + // 移除掉会话 [AUTO-TRANSLATED:1d786335] + //Remove the session auto strong_self = weak_self.lock(); if (!strong_self) { return; } - // 延时移除udp session, 防止频繁快速重建对象 + // 延时移除udp session, 防止频繁快速重建对象 [AUTO-TRANSLATED:50dbd694] + //Delay removing the UDP session to prevent frequent and rapid object reconstruction strong_self->_poller->doDelayTask(kUdpDelayCloseMS, [weak_self, id]() { if (auto strong_self = weak_self.lock()) { - // 从共享map中移除本session对象 + // 从共享map中移除本session对象 [AUTO-TRANSLATED:47ecbf11] + //Remove the current session object from the shared map lock_guard lck(*strong_self->_session_mutex); strong_self->_session_map->erase(id); } @@ -303,9 +331,11 @@ SessionHelper::Ptr UdpServer::createSession(const PeerIdType &id, Buffer::Ptr &b }); }); - // 获取会话强应用 + // 获取会话强应用 [AUTO-TRANSLATED:42283ea0] + //Get a strong reference to the session if (auto strong_helper = weak_helper.lock()) { - // 触发 onError 事件回调 + // 触发 onError 事件回调 [AUTO-TRANSLATED:82070c3c] + //Trigger the onError event callback TraceP(strong_helper->session()) << strong_helper->className() << " on err: " << err; strong_helper->enable = false; strong_helper->session()->onError(err); @@ -318,19 +348,24 @@ SessionHelper::Ptr UdpServer::createSession(const PeerIdType &id, Buffer::Ptr &b }; if (socket->getPoller()->isCurrentThread()) { - // 该socket分配在本线程,直接创建helper对象 + // 该socket分配在本线程,直接创建helper对象 [AUTO-TRANSLATED:18c9d95b] + //This socket is allocated in this thread, directly create a helper object return helper_creator(); } - // 该socket分配在其他线程,需要先转移走buffer,然后在其所在线程创建helper对象并处理数据 + // 该socket分配在其他线程,需要先转移走buffer,然后在其所在线程创建helper对象并处理数据 [AUTO-TRANSLATED:7816a13f] + //This socket is allocated in another thread, need to transfer the buffer first, then create a helper object in its thread and process the data auto cacheable_buf = std::move(buf); socket->getPoller()->async([helper_creator, cacheable_buf]() { - // 在该socket所在线程创建helper对象 + // 在该socket所在线程创建helper对象 [AUTO-TRANSLATED:db8d6622] + //Create a helper object in the thread where the socket is located auto helper = helper_creator(); if (helper) { - // 可能未实质创建hlepr对象成功,可能获取到其他线程创建的helper对象 + // 可能未实质创建hlepr对象成功,可能获取到其他线程创建的helper对象 [AUTO-TRANSLATED:091f648e] + //May not have actually created a helper object successfully, may have obtained a helper object created by another thread helper->session()->getPoller()->async([helper, cacheable_buf]() { - // 该数据不能丢弃,给session对象消费 + // 该数据不能丢弃,给session对象消费 [AUTO-TRANSLATED:6941e5fa] + //This data cannot be discarded, provided to the session object for consumption emitSessionRecv(helper, cacheable_buf); }); } diff --git a/src/Network/UdpServer.h b/src/Network/UdpServer.h index 41d761aee..63c6129f9 100644 --- a/src/Network/UdpServer.h +++ b/src/Network/UdpServer.h @@ -27,11 +27,15 @@ class UdpServer : public Server { /** * @brief 开始监听服务器 + * @brief Start listening to the server + + * [AUTO-TRANSLATED:342e9d0e] */ template void start(uint16_t port, const std::string &host = "::", const std::function &)> &cb = nullptr) { static std::string cls_name = toolkit::demangle(typeid(SessionType).name()); - // Session 创建器, 通过它创建不同类型的服务器 + // Session 创建器, 通过它创建不同类型的服务器 [AUTO-TRANSLATED:a419bcd3] + //Session creator, creates different types of servers through it _session_alloc = [cb](const UdpServer::Ptr &server, const Socket::Ptr &sock) { auto session = std::shared_ptr(new SessionType(sock), [](SessionType * ptr) { TraceP(static_cast(ptr)) << "~" << cls_name; @@ -52,11 +56,17 @@ class UdpServer : public Server { /** * @brief 获取服务器监听端口号, 服务器可以选择监听随机端口 + * @brief Get the server listening port number, the server can choose to listen to a random port + + * [AUTO-TRANSLATED:125ff8d8] */ uint16_t getPort(); /** * @brief 自定义socket构建行为 + * @brief Custom socket construction behavior + + * [AUTO-TRANSLATED:4cf98e86] */ void setOnCreateSocket(onCreateSocket cb); @@ -69,11 +79,19 @@ class UdpServer : public Server { * @brief 开始udp server * @param port 本机端口,0则随机 * @param host 监听网卡ip + * @brief Start UDP server + * @param port Local port, 0 for random + * @param host Listening network card IP + + * [AUTO-TRANSLATED:1c46778d] */ void start_l(uint16_t port, const std::string &host = "::"); /** * @brief 定时管理 Session, UDP 会话需要根据需要处理超时 + * @brief Periodically manage Session, UDP sessions need to handle timeouts as needed + + * [AUTO-TRANSLATED:86ff2f9c] */ void onManagerSession(); @@ -86,21 +104,38 @@ class UdpServer : public Server { * @param buf 数据 * @param addr 客户端地址 * @param addr_len 客户端地址长度 + * @brief Receive data, may come from server fd or peer fd + * @param is_server_fd Whether it is a server fd + * @param id Client ID + * @param buf Data + * @param addr Client address + * @param addr_len Client address length + + * [AUTO-TRANSLATED:1c02c9de] */ void onRead_l(bool is_server_fd, const PeerIdType &id, Buffer::Ptr &buf, struct sockaddr *addr, int addr_len); /** * @brief 根据对端信息获取或创建一个会话 + * @brief Get or create a session based on peer information + + * [AUTO-TRANSLATED:c7e1f0c3] */ SessionHelper::Ptr getOrCreateSession(const PeerIdType &id, Buffer::Ptr &buf, struct sockaddr *addr, int addr_len, bool &is_new); /** * @brief 创建一个会话, 同时进行必要的设置 + * @brief Create a session and perform necessary settings + + * [AUTO-TRANSLATED:355c4256] */ SessionHelper::Ptr createSession(const PeerIdType &id, Buffer::Ptr &buf, struct sockaddr *addr, int addr_len); /** * @brief 创建socket + * @brief Create a socket + + * [AUTO-TRANSLATED:c9aacad4] */ Socket::Ptr createSocket(const EventPoller::Ptr &poller, const Buffer::Ptr &buf = nullptr, struct sockaddr *addr = nullptr, int addr_len = 0); @@ -112,13 +147,16 @@ class UdpServer : public Server { Socket::Ptr _socket; std::shared_ptr _timer; onCreateSocket _on_create_socket; - //cloned server共享主server的session map,防止数据在不同server间漂移 + //cloned server共享主server的session map,防止数据在不同server间漂移 [AUTO-TRANSLATED:9a149e52] + //Cloned server shares the session map with the main server, preventing data drift between different servers std::shared_ptr _session_mutex; std::shared_ptr > _session_map; - //主server持有cloned server的引用 + //主server持有cloned server的引用 [AUTO-TRANSLATED:04a6403a] + //Main server holds a reference to the cloned server std::unordered_map _cloned_server; std::function _session_alloc; - // 对象个数统计 + // 对象个数统计 [AUTO-TRANSLATED:f4a012d0] + //Object count statistics ObjectStatistic _statistic; }; diff --git a/src/Network/sockutil.cpp b/src/Network/sockutil.cpp index 7778e2abc..95cf91661 100644 --- a/src/Network/sockutil.cpp +++ b/src/Network/sockutil.cpp @@ -145,8 +145,10 @@ uint16_t SockUtil::inet_port(const struct sockaddr *addr) { int SockUtil::setCloseWait(int fd, int second) { linger m_sLinger; - //在调用closesocket()时还有数据未发送完,允许等待 - // 若m_sLinger.l_onoff=0;则调用closesocket()后强制关闭 + //在调用closesocket()时还有数据未发送完,允许等待 [AUTO-TRANSLATED:8744ea4d] + //Allow waiting when calling closesocket() with data still to be sent + // 若m_sLinger.l_onoff=0;则调用closesocket()后强制关闭 [AUTO-TRANSLATED:07e5d642] + //Force close after calling closesocket() if m_sLinger.l_onoff = 0 m_sLinger.l_onoff = (second > 0); m_sLinger.l_linger = second; //设置等待时间为x秒 int ret = setsockopt(fd, SOL_SOCKET, SO_LINGER, (char *) &m_sLinger, sizeof(linger)); @@ -340,11 +342,13 @@ class DnsCache { lock_guard lck(_mtx); auto it = _dns_cache.find(host); if (it == _dns_cache.end()) { - //没有记录 + //没有记录 [AUTO-TRANSLATED:e99e45df] + //No record return nullptr; } if (it->second.create_time + expireSec < time(nullptr)) { - //已过期 + //已过期 [AUTO-TRANSLATED:5dbe0c9a] + //Expired _dns_cache.erase(it); return nullptr; } @@ -361,7 +365,8 @@ class DnsCache { std::shared_ptr getSystemDomainIP(const char *host) { struct addrinfo *answer = nullptr; - //阻塞式dns解析,可能被打断 + //阻塞式dns解析,可能被打断 [AUTO-TRANSLATED:89c8546f] + //Blocking DNS resolution, may be interrupted int ret = -1; do { ret = getaddrinfo(host, nullptr, nullptr, &answer); @@ -460,9 +465,11 @@ static int bind_sock(int fd, const char *ifr_ip, uint16_t port, int family) { int SockUtil::connect(const char *host, uint16_t port, bool async, const char *local_ip, uint16_t local_port) { sockaddr_storage addr; - //优先使用ipv4地址 + //优先使用ipv4地址 [AUTO-TRANSLATED:b7857afe] + //Prefer IPv4 address if (!getDomainIP(host, port, addr, AF_INET, SOCK_STREAM, IPPROTO_TCP)) { - //dns解析失败 + //dns解析失败 [AUTO-TRANSLATED:1d0cd32d] + //DNS resolution failed return -1; } @@ -487,11 +494,13 @@ int SockUtil::connect(const char *host, uint16_t port, bool async, const char *l } if (::connect(sockfd, (sockaddr *) &addr, get_sock_len((sockaddr *)&addr)) == 0) { - //同步连接成功 + //同步连接成功 [AUTO-TRANSLATED:da143548] + //Synchronous connection successful return sockfd; } if (async && get_uv_error(true) == UV_EAGAIN) { - //异步连接成功 + //异步连接成功 [AUTO-TRANSLATED:44ac1cad] + //Asynchronous connection successful return sockfd; } WarnL << "Connect socket to " << host << " " << port << " failed: " << get_uv_errmsg(true); @@ -516,7 +525,8 @@ int SockUtil::listen(const uint16_t port, const char *local_ip, int back_log) { return -1; } - //开始监听 + //开始监听 [AUTO-TRANSLATED:4404b1a8] + //Start listening if (::listen(fd, back_log) == -1) { WarnL << "Listen socket failed: " << get_uv_errmsg(true); close(fd); @@ -625,7 +635,8 @@ void for_each_netAdapter_win32(FUN && fun) { //type: PIP_ADAPTER_INFO } adapterPtr = adapterPtr->Next; } - //释放内存空间 + //释放内存空间 [AUTO-TRANSLATED:5310c138] + //Release memory space delete[] adapterList; } #endif //defined(_WIN32) @@ -635,7 +646,8 @@ template void for_each_netAdapter_posix(FUN &&fun){ //type: struct ifreq * struct ifconf ifconf; char buf[1024 * 10]; - //初始化ifconf + //初始化ifconf [AUTO-TRANSLATED:d9c144ee] + //Initialize ifconf ifconf.ifc_len = sizeof(buf); ifconf.ifc_buf = buf; int sockfd = ::socket(AF_INET, SOCK_DGRAM, 0); @@ -649,7 +661,8 @@ void for_each_netAdapter_posix(FUN &&fun){ //type: struct ifreq * return; } close(sockfd); - //接下来一个一个的获取IP地址 + //接下来一个一个的获取IP地址 [AUTO-TRANSLATED:6484a8b6] + //Get IP addresses one by one next struct ifreq * adapter = (struct ifreq*) buf; for (int i = (ifconf.ifc_len / sizeof(struct ifreq)); i > 0; --i,++adapter) { if(fun(adapter)){ @@ -661,23 +674,38 @@ void for_each_netAdapter_posix(FUN &&fun){ //type: struct ifreq * bool check_ip(string &address, const string &ip) { if (ip != "127.0.0.1" && ip != "0.0.0.0") { - /*获取一个有效IP*/ + /*获取一个有效IP + /* Get a valid IP + * [AUTO-TRANSLATED:72b34922] + */ address = ip; uint32_t addressInNetworkOrder = htonl(inet_addr(ip.data())); if (/*(addressInNetworkOrder >= 0x0A000000 && addressInNetworkOrder < 0x0E000000) ||*/ (addressInNetworkOrder >= 0xAC100000 && addressInNetworkOrder < 0xAC200000) || (addressInNetworkOrder >= 0xC0A80000 && addressInNetworkOrder < 0xC0A90000)) { - //A类私有IP地址: + //A类私有IP地址: [AUTO-TRANSLATED:ef542777] + //A-class private IP address: + //10.0.0.0~10.255.255.255 [AUTO-TRANSLATED:dbbf8c5f] //10.0.0.0~10.255.255.255 - //B类私有IP地址: + //B类私有IP地址: [AUTO-TRANSLATED:7dfef625] + //B-class private IP address: + //172.16.0.0~172.31.255.255 [AUTO-TRANSLATED:a96262fa] //172.16.0.0~172.31.255.255 - //C类私有IP地址: + //C类私有IP地址: [AUTO-TRANSLATED:dc37505e] + //C-class private IP address: + //192.168.0.0~192.168.255.255 [AUTO-TRANSLATED:c8c47e43] //192.168.0.0~192.168.255.255 - //如果是私有地址 说明在nat内部 + //如果是私有地址 说明在nat内部 [AUTO-TRANSLATED:92007abb] + //If it's a private address, it's inside the NAT /* 优先采用局域网地址,该地址很可能是wifi地址 * 一般来说,无线路由器分配的地址段是BC类私有ip地址 * 而A类地址多用于蜂窝移动网络 + /* Prefer to use the local area network address, this address is likely to be the WiFi address + * Generally, the address segment allocated by the wireless router is a BC-class private IP address + * While A-class addresses are often used for cellular mobile networks + + * [AUTO-TRANSLATED:134ad072] */ return true; } @@ -792,7 +820,8 @@ int SockUtil::dissolveUdpSock(int fd) { } addr.ss_family = AF_UNSPEC; if (-1 == ::connect(fd, (struct sockaddr *)&addr, addr_len) && get_uv_error() != UV_EAFNOSUPPORT) { - // mac/ios时返回EAFNOSUPPORT错误 + // mac/ios时返回EAFNOSUPPORT错误 [AUTO-TRANSLATED:bbe0621c] + //Returns EAFNOSUPPORT error on Mac/IOS WarnL << "Connect socket AF_UNSPEC failed: " << get_uv_errmsg(true); return -1; } @@ -816,7 +845,8 @@ string SockUtil::get_ifr_ip(const char *if_name) { IP_ADDR_STRING *ipAddr = &(adapter->IpAddressList); while (ipAddr){ if (strcmp(if_name,adapter->AdapterName) == 0){ - //ip匹配到了 + //ip匹配到了 [AUTO-TRANSLATED:6224132d] + //IP matched ret.assign(ipAddr->IpAddress.String); return true; } @@ -856,7 +886,8 @@ string SockUtil::get_ifr_name(const char *local_ip) { IP_ADDR_STRING *ipAddr = &(adapter->IpAddressList); while (ipAddr){ if (strcmp(local_ip,ipAddr->IpAddress.String) == 0){ - //ip匹配到了 + //ip匹配到了 [AUTO-TRANSLATED:6224132d] + //IP matched ret.assign(adapter->AdapterName); return true; } @@ -894,9 +925,11 @@ string SockUtil::get_ifr_mask(const char *if_name) { string ret; for_each_netAdapter_win32([&](PIP_ADAPTER_INFO adapter) { if (strcmp(if_name,adapter->AdapterName) == 0){ - //找到了该网卡 + //找到了该网卡 [AUTO-TRANSLATED:c56438bb] + //Found the network card IP_ADDR_STRING *ipAddr = &(adapter->IpAddressList); - //获取第一个ip的子网掩码 + //获取第一个ip的子网掩码 [AUTO-TRANSLATED:b6df1b9d] + //Get the subnet mask of the first IP ret.assign(ipAddr->IpMask.String); return true; } @@ -938,7 +971,8 @@ string SockUtil::get_ifr_brdaddr(const char *if_name) { string ret; for_each_netAdapter_win32([&](PIP_ADAPTER_INFO adapter) { if (strcmp(if_name, adapter->AdapterName) == 0) { - //找到该网卡 + //找到该网卡 [AUTO-TRANSLATED:23a900ba] + //Found the network card IP_ADDR_STRING *ipAddr = &(adapter->IpAddressList); in_addr broadcast; broadcast.S_un.S_addr = (inet_addr(ipAddr->IpAddress.String) & inet_addr(ipAddr->IpMask.String)) | (~inet_addr(ipAddr->IpMask.String)); @@ -1121,14 +1155,16 @@ struct sockaddr_storage SockUtil::make_sockaddr(const char *host, uint16_t port) struct in_addr addr; struct in6_addr addr6; if (1 == inet_pton(AF_INET, host, &addr)) { - // host是ipv4 + // host是ipv4 [AUTO-TRANSLATED:ba5c03a7] + //Host is IPv4 reinterpret_cast(storage).sin_addr = addr; reinterpret_cast(storage).sin_family = AF_INET; reinterpret_cast(storage).sin_port = htons(port); return storage; } if (1 == inet_pton(AF_INET6, host, &addr6)) { - // host是ipv6 + // host是ipv6 [AUTO-TRANSLATED:8048db0f] + //Host is IPv6 reinterpret_cast(storage).sin6_addr = addr6; reinterpret_cast(storage).sin6_family = AF_INET6; reinterpret_cast(storage).sin6_port = htons(port); diff --git a/src/Network/sockutil.h b/src/Network/sockutil.h index 9f7af5c1a..07c038881 100644 --- a/src/Network/sockutil.h +++ b/src/Network/sockutil.h @@ -58,7 +58,8 @@ int close(int fd); #define TCP_KEEPALIVE_PROBE_TIMES 9 #define TCP_KEEPALIVE_TIME 120 -//套接字工具类,封装了socket、网络的一些基本操作 +//套接字工具类,封装了socket、网络的一些基本操作 [AUTO-TRANSLATED:33a88b27] +//Socket tool class, encapsulating some basic socket and network operations class SockUtil { public: /** @@ -69,6 +70,15 @@ class SockUtil { * @param local_ip 绑定的本地网卡ip * @param local_port 绑定的本地端口号 * @return -1代表失败,其他为socket fd号 + * Create a TCP client socket and connect to the server + * @param host Server IP or domain name + * @param port Server port number + * @param async Whether to connect asynchronously + * @param local_ip Local network card IP to bind + * @param local_port Local port number to bind + * @return -1 represents failure, others are socket fd numbers + + * [AUTO-TRANSLATED:3f0a872c] */ static int connect(const char *host, uint16_t port, bool async = true, const char *local_ip = "::", uint16_t local_port = 0); @@ -78,6 +88,13 @@ class SockUtil { * @param local_ip 绑定的本地网卡ip * @param back_log accept列队长度 * @return -1代表失败,其他为socket fd号 + * Create a TCP listening socket + * @param port Local port to listen on + * @param local_ip Local network card IP to bind + * @param back_log Accept queue length + * @return -1 represents failure, others are socket fd numbers + + * [AUTO-TRANSLATED:d56ad901] */ static int listen(const uint16_t port, const char *local_ip = "::", int back_log = 1024); @@ -87,6 +104,13 @@ class SockUtil { * @param local_ip 绑定的本地网卡ip * @param enable_reuse 是否允许重复bind端口 * @return -1代表失败,其他为socket fd号 + * Create a UDP socket + * @param port Local port to listen on + * @param local_ip Local network card IP to bind + * @param enable_reuse Whether to allow repeated bind port + * @return -1 represents failure, others are socket fd numbers + + * [AUTO-TRANSLATED:a3762f0f] */ static int bindUdpSock(const uint16_t port, const char *local_ip = "::", bool enable_reuse = true); @@ -94,6 +118,11 @@ class SockUtil { * @brief 解除与 sock 相关的绑定关系 * @param sock, socket fd 号 * @return 0 成功, -1 失败 + * @brief Release the binding relationship related to sock + * @param sock, socket fd number + * @return 0 Success, -1 Failure + + * [AUTO-TRANSLATED:50b002e8] */ static int dissolveUdpSock(int sock); @@ -102,6 +131,12 @@ class SockUtil { * @param fd socket fd号 * @param on 是否开启 * @return 0代表成功,-1为失败 + * Enable TCP_NODELAY to reduce TCP interaction delay + * @param fd socket fd number + * @param on Whether to enable + * @return 0 represents success, -1 represents failure + + * [AUTO-TRANSLATED:11b57392] */ static int setNoDelay(int fd, bool on = true); @@ -109,6 +144,11 @@ class SockUtil { * 写socket不触发SIG_PIPE信号(貌似只有mac有效) * @param fd socket fd号 * @return 0代表成功,-1为失败 + * Write socket does not trigger SIG_PIPE signal (seems to be effective only on Mac) + * @param fd socket fd number + * @return 0 represents success, -1 represents failure + + * [AUTO-TRANSLATED:bdb49ca5] */ static int setNoSigpipe(int fd); @@ -117,6 +157,12 @@ class SockUtil { * @param fd socket fd号 * @param noblock 是否阻塞 * @return 0代表成功,-1为失败 + * Set whether the read and write socket is blocked + * @param fd socket fd number + * @param noblock Whether to block + * @return 0 represents success, -1 represents failure + + * [AUTO-TRANSLATED:2f9717df] */ static int setNoBlocked(int fd, bool noblock = true); @@ -126,6 +172,13 @@ class SockUtil { * @param fd socket fd号 * @param size 接收缓存大小 * @return 0代表成功,-1为失败 + * Set the socket receive buffer, default is around 8K, generally has an upper limit + * Can be adjusted through kernel configuration file + * @param fd socket fd number + * @param size Receive buffer size + * @return 0 represents success, -1 represents failure + + * [AUTO-TRANSLATED:4dcaa8b8] */ static int setRecvBuf(int fd, int size = SOCKET_DEFAULT_BUF_SIZE); @@ -135,6 +188,13 @@ class SockUtil { * @param fd socket fd号 * @param size 接收缓存大小 * @return 0代表成功,-1为失败 + * Set the socket receive buffer, default is around 8K, generally has an upper limit + * Can be adjusted through kernel configuration file + * @param fd socket fd number + * @param size Receive buffer size + * @return 0 represents success, -1 represents failure + + * [AUTO-TRANSLATED:4dcaa8b8] */ static int setSendBuf(int fd, int size = SOCKET_DEFAULT_BUF_SIZE); @@ -143,6 +203,12 @@ class SockUtil { * @param fd socket fd号 * @param on 是否开启该特性 * @return 0代表成功,-1为失败 + * Set subsequent bindable reuse port (in TIME_WAIT state) + * @param fd socket fd number + * @param on whether to enable this feature + * @return 0 represents success, -1 for failure + + * [AUTO-TRANSLATED:4dcb4dff] */ static int setReuseable(int fd, bool on = true, bool reuse_port = true); @@ -151,6 +217,12 @@ class SockUtil { * @param fd socket fd号 * @param on 是否开启该特性 * @return 0代表成功,-1为失败 + * Run sending or receiving UDP broadcast messages + * @param fd socket fd number + * @param on whether to enable this feature + * @return 0 represents success, -1 for failure + + * [AUTO-TRANSLATED:d5ce73e0] */ static int setBroadcast(int fd, bool on = true); @@ -162,6 +234,15 @@ class SockUtil { * @param interval keepalive探测时间间隔 * @param times keepalive探测次数 * @return 0代表成功,-1为失败 + * Enable TCP KeepAlive feature + * @param fd socket fd number + * @param on whether to enable this feature + * @param idle keepalive idle time + * @param interval keepalive probe time interval + * @param times keepalive probe times + * @return 0 represents success, -1 for failure + + * [AUTO-TRANSLATED:9b44a8ec] */ static int setKeepAlive(int fd, bool on = true, int interval = TCP_KEEPALIVE_INTERVAL, int idle = TCP_KEEPALIVE_TIME, int times = TCP_KEEPALIVE_PROBE_TIMES); @@ -170,6 +251,12 @@ class SockUtil { * @param fd fd号,不一定是socket * @param on 是否开启该特性 * @return 0代表成功,-1为失败 + * Enable FD_CLOEXEC feature (related to multiple processes) + * @param fd fd number, not necessarily a socket + * @param on whether to enable this feature + * @return 0 represents success, -1 for failure + + * [AUTO-TRANSLATED:964368da] */ static int setCloExec(int fd, bool on = true); @@ -178,6 +265,12 @@ class SockUtil { * @param sock socket fd号 * @param second 内核等待关闭socket超时时间,单位秒 * @return 0代表成功,-1为失败 + * Enable SO_LINGER feature + * @param sock socket fd number + * @param second kernel waiting time for closing socket timeout, in seconds + * @return 0 represents success, -1 for failure + + * [AUTO-TRANSLATED:92230daf] */ static int setCloseWait(int sock, int second = 0); @@ -187,6 +280,13 @@ class SockUtil { * @param port 端口号 * @param addr sockaddr结构体 * @return 是否成功 + * DNS resolution + * @param host domain name or IP + * @param port port number + * @param addr sockaddr structure + * @return whether successful + + * [AUTO-TRANSLATED:3b79cf5d] */ static bool getDomainIP(const char *host, uint16_t port, struct sockaddr_storage &addr, int ai_family = AF_INET, int ai_socktype = SOCK_STREAM, int ai_protocol = IPPROTO_TCP, int expire_sec = 60); @@ -196,6 +296,12 @@ class SockUtil { * @param sock socket fd号 * @param ttl ttl值 * @return 0代表成功,-1为失败 + * Set multicast TTL + * @param sock socket fd number + * @param ttl TTL value + * @return 0 represents success, -1 for failure + + * [AUTO-TRANSLATED:1828beb5] */ static int setMultiTTL(int sock, uint8_t ttl = 64); @@ -204,6 +310,12 @@ class SockUtil { * @param sock socket fd号 * @param local_ip 本机网卡ip * @return 0代表成功,-1为失败 + * Set multicast sending network card + * @param sock socket fd number + * @param local_ip local network card IP + * @return 0 represents success, -1 for failure + + * [AUTO-TRANSLATED:25e8e9d7] */ static int setMultiIF(int sock, const char *local_ip); @@ -212,6 +324,12 @@ class SockUtil { * @param fd socket fd号 * @param acc 是否接收 * @return 0代表成功,-1为失败 + * Set whether to receive multicast packets sent by the local machine + * @param fd socket fd number + * @param acc whether to receive + * @return 0 represents success, -1 for failure + + * [AUTO-TRANSLATED:83cec1e8] */ static int setMultiLOOP(int fd, bool acc = false); @@ -221,6 +339,13 @@ class SockUtil { * @param addr 组播地址 * @param local_ip 本机网卡ip * @return 0代表成功,-1为失败 + * Join multicast + * @param fd socket fd number + * @param addr multicast address + * @param local_ip local network card IP + * @return 0 represents success, -1 for failure + + * [AUTO-TRANSLATED:45523b25] */ static int joinMultiAddr(int fd, const char *addr, const char *local_ip = "0.0.0.0"); @@ -230,6 +355,13 @@ class SockUtil { * @param addr 组播地址 * @param local_ip 本机网卡ip * @return 0代表成功,-1为失败 + * Exit multicast + * @param fd socket fd number + * @param addr multicast address + * @param local_ip local network card ip + * @return 0 represents success, -1 for failure + + * [AUTO-TRANSLATED:081785d3] */ static int leaveMultiAddr(int fd, const char *addr, const char *local_ip = "0.0.0.0"); @@ -240,6 +372,14 @@ class SockUtil { * @param src_ip 数据源端地址 * @param local_ip 本机网卡ip * @return 0代表成功,-1为失败 + * Join multicast and only receive multicast data from the specified source + * @param sock socket fd number + * @param addr multicast address + * @param src_ip source address + * @param local_ip local network card ip + * @return 0 represents success, -1 for failure + + * [AUTO-TRANSLATED:061989eb] */ static int joinMultiAddrFilter(int sock, const char *addr, const char *src_ip, const char *local_ip = "0.0.0.0"); @@ -250,6 +390,14 @@ class SockUtil { * @param src_ip 数据源端地址 * @param local_ip 本机网卡ip * @return 0代表成功,-1为失败 + * Exit multicast + * @param fd socket fd number + * @param addr multicast address + * @param src_ip source address + * @param local_ip local network card ip + * @return 0 represents success, -1 for failure + + * [AUTO-TRANSLATED:9cd166c7] */ static int leaveMultiAddrFilter(int fd, const char *addr, const char *src_ip, const char *local_ip = "0.0.0.0"); @@ -257,47 +405,78 @@ class SockUtil { * 获取该socket当前发生的错误 * @param fd socket fd号 * @return 错误代码 + * Get the current error of the socket + * @param fd socket fd number + * @return error code + + * [AUTO-TRANSLATED:e4500a0f] */ static int getSockError(int fd); /** * 获取网卡列表 * @return vector > + * Get the list of network cards + * @return vector > + + * [AUTO-TRANSLATED:94687465] */ static std::vector> getInterfaceList(); /** * 获取本机默认网卡ip + * Get the default local ip of the host + + * [AUTO-TRANSLATED:9eb5d031] */ static std::string get_local_ip(); /** * 获取该socket绑定的本地ip * @param sock socket fd号 + * Get the local ip bound to the socket + * @param sock socket fd number + + * [AUTO-TRANSLATED:4e7b6040] */ static std::string get_local_ip(int sock); /** * 获取该socket绑定的本地端口 * @param sock socket fd号 + * Get the local port bound to the socket + * @param sock socket fd number + + * [AUTO-TRANSLATED:7b212118] */ static uint16_t get_local_port(int sock); /** * 获取该socket绑定的远端ip * @param sock socket fd号 + * Get the remote ip bound to the socket + * @param sock socket fd number + + * [AUTO-TRANSLATED:952ddef8] */ static std::string get_peer_ip(int sock); /** * 获取该socket绑定的远端端口 * @param sock socket fd号 + * Get the remote port bound to the socket + * @param sock socket fd number + + * [AUTO-TRANSLATED:3b9bcf2e] */ static uint16_t get_peer_port(int sock); static bool support_ipv6(); /** * 线程安全的in_addr转ip字符串 + * Thread-safe conversion of in_addr to IP string + + * [AUTO-TRANSLATED:e0ff8b4b] */ static std::string inet_ntoa(const struct in_addr &addr); static std::string inet_ntoa(const struct in6_addr &addr); @@ -311,24 +490,40 @@ class SockUtil { /** * 获取网卡ip * @param if_name 网卡名 + * Get the IP of the network card + * @param if_name Network card name + + * [AUTO-TRANSLATED:e88f1554] */ static std::string get_ifr_ip(const char *if_name); /** * 获取网卡名 * @param local_op 网卡ip + * Get the network card name + * @param local_op Network card IP + + * [AUTO-TRANSLATED:cdaad7f0] */ static std::string get_ifr_name(const char *local_op); /** * 根据网卡名获取子网掩码 * @param if_name 网卡名 + * Get the subnet mask based on the network card name + * @param if_name Network card name + + * [AUTO-TRANSLATED:a6714ee2] */ static std::string get_ifr_mask(const char *if_name); /** * 根据网卡名获取广播地址 * @param if_name 网卡名 + * Get the broadcast address based on the network card name + * @param if_name Network card name + + * [AUTO-TRANSLATED:20348c92] */ static std::string get_ifr_brdaddr(const char *if_name); @@ -336,16 +531,27 @@ class SockUtil { * 判断两个ip是否为同一网段 * @param src_ip 我的ip * @param dts_ip 对方ip + * Determine if two IPs are in the same network segment + * @param src_ip My IP + * @param dts_ip Peer IP + + * [AUTO-TRANSLATED:95acb68f] */ static bool in_same_lan(const char *src_ip, const char *dts_ip); /** * 判断是否为ipv4地址 + * Determine if it is an IPv4 address + + * [AUTO-TRANSLATED:b5af4ea0] */ static bool is_ipv4(const char *str); /** * 判断是否为ipv6地址 + * Determine if it is an IPv6 address + + * [AUTO-TRANSLATED:70526900] */ static bool is_ipv6(const char *str); }; diff --git a/src/Poller/EventPoller.cpp b/src/Poller/EventPoller.cpp index 54d26f8db..700e1babb 100644 --- a/src/Poller/EventPoller.cpp +++ b/src/Poller/EventPoller.cpp @@ -25,7 +25,8 @@ #define EPOLL_SIZE 1024 -//防止epoll惊群 +//防止epoll惊群 [AUTO-TRANSLATED:ad53c775] +//Prevent epoll thundering #ifndef EPOLLEXCLUSIVE #define EPOLLEXCLUSIVE 0 #endif @@ -60,7 +61,8 @@ void EventPoller::addEventPipe() { SockUtil::setNoBlocked(_pipe.readFD()); SockUtil::setNoBlocked(_pipe.writeFD()); - // 添加内部管道事件 + // 添加内部管道事件 [AUTO-TRANSLATED:6a72e39a] + //Add internal pipe event if (addEvent(_pipe.readFD(), EventPoller::Event_Read, [this](int event) { onPipeEvent(); }) == -1) { throw std::runtime_error("Add pipe fd to poller failed"); } @@ -86,7 +88,8 @@ void EventPoller::shutdown() { }, false, true); if (_loop_thread) { - //防止作为子进程时崩溃 + //防止作为子进程时崩溃 [AUTO-TRANSLATED:68727e34] + //Prevent crash when running as a child process try { _loop_thread->join(); } catch (...) { _loop_thread->detach(); } delete _loop_thread; _loop_thread = nullptr; @@ -103,7 +106,8 @@ EventPoller::~EventPoller() { } #endif - //退出前清理管道中的数据 + //退出前清理管道中的数据 [AUTO-TRANSLATED:60e26f9a] + //Clean up pipe data before exiting onPipeEvent(true); InfoL << getThreadName(); } @@ -141,7 +145,8 @@ int EventPoller::addEvent(int fd, int event, PollEventCB cb) { return ret; #else #ifndef _WIN32 - // win32平台,socket套接字不等于文件描述符,所以可能不适用这个限制 + // win32平台,socket套接字不等于文件描述符,所以可能不适用这个限制 [AUTO-TRANSLATED:6adfc664] + //On the win32 platform, the socket does not equal the file descriptor, so this restriction may not apply if (fd >= FD_SETSIZE) { WarnL << "select() can not watch fd bigger than " << FD_SETSIZE; return -1; @@ -200,7 +205,8 @@ int EventPoller::delEvent(int fd, PollCompleteCB cb) { #endif //HAS_EPOLL } - //跨线程操作 + //跨线程操作 [AUTO-TRANSLATED:4e116519] + //Cross-thread operation async([this, fd, cb]() mutable { delEvent(fd, std::move(cb)); }); @@ -267,7 +273,8 @@ Task::Ptr EventPoller::async_l(TaskIn task, bool may_sync, bool first) { _list_task.emplace_back(ret); } } - //写数据到管道,唤醒主线程 + //写数据到管道,唤醒主线程 [AUTO-TRANSLATED:2ead8182] + //Write data to the pipe and wake up the main thread _pipe.write("", 1); return ret; } @@ -282,11 +289,13 @@ inline void EventPoller::onPipeEvent(bool flush) { if (!flush) { for (;;) { if ((err = _pipe.read(buf, sizeof(buf))) > 0) { - // 读到管道数据,继续读,直到读空为止 + // 读到管道数据,继续读,直到读空为止 [AUTO-TRANSLATED:47bd325c] + //Read data from the pipe, continue reading until it's empty continue; } if (err == 0 || get_uv_error(true) != UV_EAGAIN) { - // 收到eof或非EAGAIN(无更多数据)错误,说明管道无效了,重新打开管道 + // 收到eof或非EAGAIN(无更多数据)错误,说明管道无效了,重新打开管道 [AUTO-TRANSLATED:5f7a013d] + //Received eof or non-EAGAIN (no more data) error, indicating that the pipe is invalid, reopen the pipe ErrorL << "Invalid pipe fd of event poller, reopen it"; delEvent(_pipe.readFD()); _pipe.reOpen(); @@ -315,7 +324,8 @@ inline void EventPoller::onPipeEvent(bool flush) { SocketRecvBuffer::Ptr EventPoller::getSharedBuffer(bool is_udp) { #if !defined(__linux) && !defined(__linux__) - // 非Linux平台下,tcp和udp共享recvfrom方案,使用同一个buffer + // 非Linux平台下,tcp和udp共享recvfrom方案,使用同一个buffer [AUTO-TRANSLATED:2d2ee7bf] + //On non-Linux platforms, tcp and udp share the recvfrom scheme, using the same buffer is_udp = 0; #endif auto ret = _shared_buffer[is_udp].lock(); @@ -357,7 +367,8 @@ void EventPoller::runLoop(bool blocked, bool ref_self) { int ret = epoll_wait(_event_fd, events, EPOLL_SIZE, minDelay ? minDelay : -1); sleepWakeUp();//用于统计当前线程负载情况 if (ret <= 0) { - //超时或被打断 + //超时或被打断 [AUTO-TRANSLATED:7005fded] + //Timed out or interrupted continue; } @@ -434,7 +445,8 @@ void EventPoller::runLoop(bool blocked, bool ref_self) { List callback_list; struct timeval tv; while (!_exit_flag) { - //定时器事件中可能操作_event_map + //定时器事件中可能操作_event_map [AUTO-TRANSLATED:f2a50ee2] + //Possible operations on _event_map in timer events minDelay = getMinDelay(); tv.tv_sec = (decltype(tv.tv_sec)) (minDelay / 1000); tv.tv_usec = 1000 * (minDelay % 1000); @@ -463,13 +475,15 @@ void EventPoller::runLoop(bool blocked, bool ref_self) { sleepWakeUp();//用于统计当前线程负载情况 if (ret <= 0) { - //超时或被打断 + //超时或被打断 [AUTO-TRANSLATED:7005fded] + //Timed out or interrupted continue; } _event_cache_expired.clear(); - //收集select事件类型 + //收集select事件类型 [AUTO-TRANSLATED:9a5c41d3] + //Collect select event types for (auto &pr : _event_map) { int event = 0; if (set_read.isSet(pr.first)) { @@ -513,11 +527,13 @@ uint64_t EventPoller::flushDelayTask(uint64_t now_time) { task_copy.swap(_delay_task_map); for (auto it = task_copy.begin(); it != task_copy.end() && it->first <= now_time; it = task_copy.erase(it)) { - //已到期的任务 + //已到期的任务 [AUTO-TRANSLATED:849cdc29] + //Expired tasks try { auto next_delay = (*(it->second))(); if (next_delay) { - //可重复任务,更新时间截止线 + //可重复任务,更新时间截止线 [AUTO-TRANSLATED:c7746a21] + //Repeatable tasks, update deadline _delay_task_map.emplace(next_delay + now_time, std::move(it->second)); } } catch (std::exception &ex) { @@ -530,25 +546,30 @@ uint64_t EventPoller::flushDelayTask(uint64_t now_time) { auto it = _delay_task_map.begin(); if (it == _delay_task_map.end()) { - //没有剩余的定时器了 + //没有剩余的定时器了 [AUTO-TRANSLATED:23b1119e] + //No remaining timers return 0; } - //最近一个定时器的执行延时 + //最近一个定时器的执行延时 [AUTO-TRANSLATED:2535621b] + //Delay in execution of the last timer return it->first - now_time; } uint64_t EventPoller::getMinDelay() { auto it = _delay_task_map.begin(); if (it == _delay_task_map.end()) { - //没有剩余的定时器了 + //没有剩余的定时器了 [AUTO-TRANSLATED:23b1119e] + //No remaining timers return 0; } auto now = getCurrentMillisecond(); if (it->first > now) { - //所有任务尚未到期 + //所有任务尚未到期 [AUTO-TRANSLATED:8d80eabf] + //All tasks have not expired return it->first - now; } - //执行已到期的任务并刷新休眠延时 + //执行已到期的任务并刷新休眠延时 [AUTO-TRANSLATED:cd6348b7] + //Execute expired tasks and refresh sleep delay return flushDelayTask(now); } @@ -556,7 +577,8 @@ EventPoller::DelayTask::Ptr EventPoller::doDelayTask(uint64_t delay_ms, function DelayTask::Ptr ret = std::make_shared(std::move(task)); auto time_line = getCurrentMillisecond() + delay_ms; async_first([time_line, ret, this]() { - //异步执行的目的是刷新select或epoll的休眠时间 + //异步执行的目的是刷新select或epoll的休眠时间 [AUTO-TRANSLATED:a6b5c8d7] + //The purpose of asynchronous execution is to refresh the sleep time of select or epoll _delay_task_map.emplace(time_line, ret); }); return ret; diff --git a/src/Poller/EventPoller.h b/src/Poller/EventPoller.h index 728878401..e055788a9 100644 --- a/src/Poller/EventPoller.h +++ b/src/Poller/EventPoller.h @@ -58,6 +58,11 @@ class EventPoller : public TaskExecutor, public AnyStorage, public std::enable_s * 获取EventPollerPool单例中的第一个EventPoller实例, * 保留该接口是为了兼容老代码 * @return 单例 + * Gets the first EventPoller instance from the EventPollerPool singleton, + * This interface is preserved for compatibility with old code. + * @return singleton + + * [AUTO-TRANSLATED:b536ebf6] */ static EventPoller &Instance(); @@ -67,6 +72,13 @@ class EventPoller : public TaskExecutor, public AnyStorage, public std::enable_s * @param event 事件类型,例如 Event_Read | Event_Write * @param cb 事件回调functional * @return -1:失败,0:成功 + * Adds an event listener + * @param fd The file descriptor to listen to + * @param event The event type, e.g. Event_Read | Event_Write + * @param cb The event callback function + * @return -1: failed, 0: success + + * [AUTO-TRANSLATED:cfba4c75] */ int addEvent(int fd, int event, PollEventCB cb); @@ -75,6 +87,12 @@ class EventPoller : public TaskExecutor, public AnyStorage, public std::enable_s * @param fd 监听的文件描述符 * @param cb 删除成功回调functional * @return -1:失败,0:成功 + * Deletes an event listener + * @param fd The file descriptor to stop listening to + * @param cb The callback function for successful deletion + * @return -1: failed, 0: success + + * [AUTO-TRANSLATED:be6fdf51] */ int delEvent(int fd, PollCompleteCB cb = nullptr); @@ -83,6 +101,12 @@ class EventPoller : public TaskExecutor, public AnyStorage, public std::enable_s * @param fd 监听的文件描述符 * @param event 事件类型,例如 Event_Read | Event_Write * @return -1:失败,0:成功 + * Modifies the event type being listened to + * @param fd The file descriptor to modify + * @param event The new event type, e.g. Event_Read | Event_Write + * @return -1: failed, 0: success + + * [AUTO-TRANSLATED:becf3d09] */ int modifyEvent(int fd, int event, PollCompleteCB cb = nullptr); @@ -91,6 +115,13 @@ class EventPoller : public TaskExecutor, public AnyStorage, public std::enable_s * @param task 任务 * @param may_sync 如果调用该函数的线程就是本对象的轮询线程,那么may_sync为true时就是同步执行任务 * @return 是否成功,一定会返回true + * Executes a task asynchronously + * @param task The task to execute + * @param may_sync If the calling thread is the polling thread of this object, + * then if may_sync is true, the task will be executed synchronously + * @return Whether the task was executed successfully (always returns true) + + * [AUTO-TRANSLATED:071f7ed8] */ Task::Ptr async(TaskIn task, bool may_sync = true) override; @@ -99,12 +130,24 @@ class EventPoller : public TaskExecutor, public AnyStorage, public std::enable_s * @param task 任务 * @param may_sync 如果调用该函数的线程就是本对象的轮询线程,那么may_sync为true时就是同步执行任务 * @return 是否成功,一定会返回true + * Similar to async, but adds the task to the head of the task queue, + * giving it the highest priority + * @param task The task to execute + * @param may_sync If the calling thread is the polling thread of this object, + * then if may_sync is true, the task will be executed synchronously + * @return Whether the task was executed successfully (always returns true) + + * [AUTO-TRANSLATED:9ef5169b] */ Task::Ptr async_first(TaskIn task, bool may_sync = true) override; /** * 判断执行该接口的线程是否为本对象的轮询线程 * @return 是否为本对象的轮询线程 + * Checks if the thread calling this interface is the polling thread of this object + * @return Whether the calling thread is the polling thread + + * [AUTO-TRANSLATED:db9a4916] */ bool isCurrentThread(); @@ -113,32 +156,55 @@ class EventPoller : public TaskExecutor, public AnyStorage, public std::enable_s * @param delay_ms 延时毫秒数 * @param task 任务,返回值为0时代表不再重复任务,否则为下次执行延时,如果任务中抛异常,那么默认不重复任务 * @return 可取消的任务标签 + * Delays the execution of a task + * @param delay_ms The delay in milliseconds + * @param task The task to execute, returns 0 to stop repeating the task, + * otherwise returns the delay for the next execution. + * If an exception is thrown in the task, it defaults to not repeating the task. + * @return A cancellable task label + + * [AUTO-TRANSLATED:61f97e64] */ DelayTask::Ptr doDelayTask(uint64_t delay_ms, std::function task); /** * 获取当前线程关联的Poller实例 + * Gets the Poller instance associated with the current thread + + * [AUTO-TRANSLATED:debcf0e2] */ static EventPoller::Ptr getCurrentPoller(); /** * 获取当前线程下所有socket共享的读缓存 + * Gets the shared read buffer for all sockets in the current thread + + * [AUTO-TRANSLATED:2796f458] */ SocketRecvBuffer::Ptr getSharedBuffer(bool is_udp); /** * 获取poller线程id + * Get the poller thread ID + + * [AUTO-TRANSLATED:1c968752] */ std::thread::id getThreadId() const; /** * 获取线程名 + * Get the thread name + + * [AUTO-TRANSLATED:842652d9] */ const std::string& getThreadName() const; private: /** * 本对象只允许在EventPollerPool中构造 + * This object can only be constructed in EventPollerPool + + * [AUTO-TRANSLATED:0c9a8a28] */ EventPoller(std::string name); @@ -146,11 +212,19 @@ class EventPoller : public TaskExecutor, public AnyStorage, public std::enable_s * 执行事件轮询 * @param blocked 是否用执行该接口的线程执行轮询 * @param ref_self 是记录本对象到thread local变量 + * Perform event polling + * @param blocked Whether to execute polling with the thread that calls this interface + * @param ref_self Whether to record this object to thread local variable + + * [AUTO-TRANSLATED:b0ac803c] */ void runLoop(bool blocked, bool ref_self); /** * 内部管道事件,用于唤醒轮询线程用 + * Internal pipe event, used to wake up the polling thread + + * [AUTO-TRANSLATED:022754b9] */ void onPipeEvent(bool flush = false); @@ -160,27 +234,47 @@ class EventPoller : public TaskExecutor, public AnyStorage, public std::enable_s * @param may_sync * @param first * @return 可取消的任务本体,如果已经同步执行,则返回nullptr + * Switch threads and execute tasks + * @param task + * @param may_sync + * @param first + * @return The cancellable task itself, or nullptr if it has been executed synchronously + + * [AUTO-TRANSLATED:e7019c4a] */ Task::Ptr async_l(TaskIn task, bool may_sync = true, bool first = false); /** * 结束事件轮询 * 需要指出的是,一旦结束就不能再次恢复轮询线程 + * End event polling + * Note that once ended, the polling thread cannot be resumed + + * [AUTO-TRANSLATED:4f232154] */ void shutdown(); /** * 刷新延时任务 + * Refresh delayed tasks + + * [AUTO-TRANSLATED:88104b90] */ uint64_t flushDelayTask(uint64_t now); /** * 获取select或epoll休眠时间 + * Get the sleep time for select or epoll + + * [AUTO-TRANSLATED:34e0384e] */ uint64_t getMinDelay(); /** * 添加管道监听事件 + * Add pipe listening event + + * [AUTO-TRANSLATED:06e5bc67] */ void addEventPipe(); @@ -188,32 +282,52 @@ class EventPoller : public TaskExecutor, public AnyStorage, public std::enable_s class ExitException : public std::exception {}; private: + //标记loop线程是否退出 [AUTO-TRANSLATED:98250f84] //标记loop线程是否退出 +// Mark the loop thread as exited bool _exit_flag; + //线程名 [AUTO-TRANSLATED:f1d62d9f] //线程名 +// Thread name std::string _name; + //当前线程下,所有socket共享的读缓存 [AUTO-TRANSLATED:6ce70017] //当前线程下,所有socket共享的读缓存 +// Shared read buffer for all sockets under the current thread std::weak_ptr _shared_buffer[2]; + //执行事件循环的线程 [AUTO-TRANSLATED:2465cc75] //执行事件循环的线程 +// Thread that executes the event loop std::thread *_loop_thread = nullptr; + //通知事件循环的线程已启动 [AUTO-TRANSLATED:61f478cf] //通知事件循环的线程已启动 +// Notify the event loop thread that it has started semaphore _sem_run_started; + //内部事件管道 [AUTO-TRANSLATED:dc1d3a93] //内部事件管道 +// Internal event pipe PipeWrap _pipe; + //从其他线程切换过来的任务 [AUTO-TRANSLATED:d16917d6] //从其他线程切换过来的任务 +// Tasks switched from other threads std::mutex _mtx_task; List _list_task; + //保持日志可用 [AUTO-TRANSLATED:4a6c2438] //保持日志可用 +// Keep the log available Logger::Ptr _logger; #if defined(HAS_EPOLL) || defined(HAS_KQUEUE) - // epoll和kqueue相关 + // epoll和kqueue相关 [AUTO-TRANSLATED:84d2785e] + //epoll和kqueue相关 +// epoll and kqueue related int _event_fd = -1; std::unordered_map > _event_map; #else - // select相关 + // select相关 [AUTO-TRANSLATED:bf3e2edd] + //select相关 +// select related struct Poll_Record { using Ptr = std::shared_ptr; int fd; @@ -225,7 +339,8 @@ class EventPoller : public TaskExecutor, public AnyStorage, public std::enable_s #endif //HAS_EPOLL std::unordered_set _event_cache_expired; - //定时器相关 + //定时器相关 [AUTO-TRANSLATED:fa2e84da] + //Timer related std::multimap _delay_task_map; }; @@ -240,6 +355,10 @@ class EventPollerPool : public std::enable_shared_from_this, pu /** * 获取单例 * @return + * Get singleton + * @return + + * [AUTO-TRANSLATED:1cb32aa7] */ static EventPollerPool &Instance(); @@ -247,17 +366,29 @@ class EventPollerPool : public std::enable_shared_from_this, pu * 设置EventPoller个数,在EventPollerPool单例创建前有效 * 在不调用此方法的情况下,默认创建thread::hardware_concurrency()个EventPoller实例 * @param size EventPoller个数,如果为0则为thread::hardware_concurrency() + * Set the number of EventPoller instances, effective before the EventPollerPool singleton is created + * If this method is not called, the default is to create thread::hardware_concurrency() EventPoller instances + * @param size Number of EventPoller instances, 0 means thread::hardware_concurrency() + + * [AUTO-TRANSLATED:bdc02181] */ static void setPoolSize(size_t size = 0); /** * 内部创建线程是否设置cpu亲和性,默认设置cpu亲和性 + * Whether to set CPU affinity for internal thread creation, default is to set CPU affinity + + * [AUTO-TRANSLATED:46941c9f] */ static void enableCpuAffinity(bool enable); /** * 获取第一个实例 * @return + * Get the first instance + * @return + + * [AUTO-TRANSLATED:a76aad3b] */ EventPoller::Ptr getFirstPoller(); @@ -266,6 +397,12 @@ class EventPollerPool : public std::enable_shared_from_this, pu * 如果优先返回当前线程,那么会返回当前线程 * 返回当前线程的目的是为了提高线程安全性 * @param prefer_current_thread 是否优先获取当前线程 + * Get a lightly loaded instance based on the load + * If prioritizing the current thread, it will return the current thread + * The purpose of returning the current thread is to improve thread safety + * @param prefer_current_thread Whether to prioritize getting the current thread + + * [AUTO-TRANSLATED:f0830806] */ EventPoller::Ptr getPoller(bool prefer_current_thread = true); @@ -274,6 +411,12 @@ class EventPollerPool : public std::enable_shared_from_this, pu * 在批量创建Socket对象时,如果优先返回当前线程, * 那么将导致负载不够均衡,所以可以暂时关闭然后再开启 * @param flag 是否优先返回当前线程 + * Set whether getPoller() prioritizes returning the current thread + * When creating Socket objects in batches, if prioritizing the current thread, + * it will cause the load to be unbalanced, so it can be temporarily closed and then reopened + * @param flag Whether to prioritize returning the current thread + + * [AUTO-TRANSLATED:c354e1d5] */ void preferCurrentThread(bool flag = true); diff --git a/src/Poller/Timer.cpp b/src/Poller/Timer.cpp index 2512fbbef..316183403 100644 --- a/src/Poller/Timer.cpp +++ b/src/Poller/Timer.cpp @@ -20,10 +20,12 @@ Timer::Timer(float second, const std::function &cb, const EventPoller::P _tag = _poller->doDelayTask((uint64_t) (second * 1000), [cb, second]() { try { if (cb()) { - //重复的任务 + //重复的任务 [AUTO-TRANSLATED:2d440b54] + //Recurring task return (uint64_t) (1000 * second); } - //该任务不再重复 + //该任务不再重复 [AUTO-TRANSLATED:4249fc53] + //This task no longer recurs return (uint64_t) 0; } catch (std::exception &ex) { ErrorL << "Exception occurred when do timer task: " << ex.what(); diff --git a/src/Poller/Timer.h b/src/Poller/Timer.h index 99ed4190b..222da862e 100644 --- a/src/Poller/Timer.h +++ b/src/Poller/Timer.h @@ -25,13 +25,20 @@ class Timer { * @param second 定时器重复秒数 * @param cb 定时器任务,返回true表示重复下次任务,否则不重复,如果任务中抛异常,则默认重复下次任务 * @param poller EventPoller对象,可以为nullptr + * Constructs a timer + * @param second Timer repeat interval in seconds + * @param cb Timer task, returns true to repeat the next task, otherwise does not repeat. If an exception is thrown in the task, it defaults to repeating the next task + * @param poller EventPoller object, can be nullptr + + * [AUTO-TRANSLATED:7dc94698] */ Timer(float second, const std::function &cb, const EventPoller::Ptr &poller); ~Timer(); private: std::weak_ptr _tag; - //定时器保持EventPoller的强引用 + //定时器保持EventPoller的强引用 [AUTO-TRANSLATED:d171cd2f] + //Timer keeps a strong reference to EventPoller EventPoller::Ptr _poller; }; diff --git a/src/Thread/TaskExecutor.cpp b/src/Thread/TaskExecutor.cpp index 8388087f4..f47b36baf 100644 --- a/src/Thread/TaskExecutor.cpp +++ b/src/Thread/TaskExecutor.cpp @@ -93,7 +93,8 @@ void TaskExecutorInterface::sync(const TaskIn &task) { semaphore sem; auto ret = async([&]() { onceToken token(nullptr, [&]() { - //通过RAII原理防止抛异常导致不执行这句代码 + //通过RAII原理防止抛异常导致不执行这句代码 [AUTO-TRANSLATED:206bd80e] + //Prevent this code from not being executed due to an exception being thrown through RAII principle sem.post(); }); task(); @@ -107,7 +108,8 @@ void TaskExecutorInterface::sync_first(const TaskIn &task) { semaphore sem; auto ret = async_first([&]() { onceToken token(nullptr, [&]() { - //通过RAII原理防止抛异常导致不执行这句代码 + //通过RAII原理防止抛异常导致不执行这句代码 [AUTO-TRANSLATED:206bd80e] + //Prevent this code from not being executed due to an exception being thrown through RAII principle sem.post(); }); task(); @@ -165,7 +167,8 @@ vector TaskExecutorGetterImp::getExecutorLoad() { void TaskExecutorGetterImp::getExecutorDelay(const function &)> &callback) { std::shared_ptr > delay_vec = std::make_shared>(_threads.size()); shared_ptr finished(nullptr, [callback, delay_vec](void *) { - //此析构回调触发时,说明已执行完毕所有async任务 + //此析构回调触发时,说明已执行完毕所有async任务 [AUTO-TRANSLATED:8adf8212] + //When this destructor callback is triggered, it means all async tasks have been executed callback((*delay_vec)); }); int index = 0; @@ -197,11 +200,14 @@ size_t TaskExecutorGetterImp::addPoller(const string &name, size_t size, int pri EventPoller::Ptr poller(new EventPoller(full_name)); poller->runLoop(false, register_thread); poller->async([cpu_index, full_name, priority, enable_cpu_affinity]() { - // 设置线程优先级 + // 设置线程优先级 [AUTO-TRANSLATED:2966f860] + //Set thread priority ThreadPool::setPriority((ThreadPool::Priority)priority); - // 设置线程名 + // 设置线程名 [AUTO-TRANSLATED:f5eb4704] + //Set thread name setThreadName(full_name.data()); - // 设置cpu亲和性 + // 设置cpu亲和性 [AUTO-TRANSLATED:ba213aed] + //Set CPU affinity if (enable_cpu_affinity) { setThreadAffinity(cpu_index); } diff --git a/src/Thread/TaskExecutor.h b/src/Thread/TaskExecutor.h index efbbfc846..df5dec65b 100644 --- a/src/Thread/TaskExecutor.h +++ b/src/Thread/TaskExecutor.h @@ -21,6 +21,9 @@ namespace toolkit { /** * cpu负载计算器 + * CPU Load Calculator + + * [AUTO-TRANSLATED:46dad663] */ class ThreadLoadCounter { public: @@ -28,23 +31,38 @@ class ThreadLoadCounter { * 构造函数 * @param max_size 统计样本数量 * @param max_usec 统计时间窗口,亦即最近{max_usec}的cpu负载率 + * Constructor + * @param max_size Number of statistical samples + * @param max_usec Statistical time window, i.e., the CPU load rate for the most recent {max_usec} + + * [AUTO-TRANSLATED:718cb173] */ ThreadLoadCounter(uint64_t max_size, uint64_t max_usec); ~ThreadLoadCounter() = default; /** * 线程进入休眠 + * Thread enters sleep + + * [AUTO-TRANSLATED:d831fad1] */ void startSleep(); /** * 休眠唤醒,结束休眠 + * Wake up from sleep, end sleep + + * [AUTO-TRANSLATED:361831f8] */ void sleepWakeUp(); /** * 返回当前线程cpu使用率,范围为 0 ~ 100 * @return 当前线程cpu使用率 + * Returns the current thread's CPU usage rate, ranging from 0 to 100 + * @return Current thread's CPU usage rate + + * [AUTO-TRANSLATED:c9953342] */ int load(); @@ -147,6 +165,12 @@ class TaskExecutorInterface { * @param task 任务 * @param may_sync 是否允许同步执行该任务 * @return 任务是否添加成功 + * Asynchronously execute a task + * @param task Task + * @param may_sync Whether to allow synchronous execution of the task + * @return Whether the task was added successfully + + * [AUTO-TRANSLATED:271d48a2] */ virtual Task::Ptr async(TaskIn task, bool may_sync = true) = 0; @@ -155,6 +179,12 @@ class TaskExecutorInterface { * @param task 任务 * @param may_sync 是否允许同步执行该任务 * @return 任务是否添加成功 + * Asynchronously execute a task with the highest priority + * @param task Task + * @param may_sync Whether to allow synchronous execution of the task + * @return Whether the task was added successfully + + * [AUTO-TRANSLATED:d52ce80b] */ virtual Task::Ptr async_first(TaskIn task, bool may_sync = true); @@ -162,6 +192,11 @@ class TaskExecutorInterface { * 同步执行任务 * @param task * @return + * Synchronously execute a task + * @param task + * @return + + * [AUTO-TRANSLATED:24854b4a] */ void sync(const TaskIn &task); @@ -169,12 +204,20 @@ class TaskExecutorInterface { * 最高优先级方式同步执行任务 * @param task * @return + * Synchronously execute a task with the highest priority + * @param task + * @return + + * [AUTO-TRANSLATED:3d15452d] */ void sync_first(const TaskIn &task); }; /** * 任务执行器 + * Task Executor + + * [AUTO-TRANSLATED:630c364f] */ class TaskExecutor : public ThreadLoadCounter, public TaskExecutorInterface { public: @@ -184,6 +227,8 @@ class TaskExecutor : public ThreadLoadCounter, public TaskExecutorInterface { * 构造函数 * @param max_size cpu负载统计样本数 * @param max_usec cpu负载统计时间窗口大小 + fade fade оч fadeSalvar :::.Enums fade fade fade fade оч fade fade fade fade ::: fade fade fade fade fade fade fade fade_Checked fade fade fade fade_TYPEDEF fade fade fade fade fadeSalvar fade fade fade fade.Enums fade fade fade оч fade fade fade_Checked_Checked fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade оч fade fade fade fade fade_Checked fade fade fade fade fade оч fade fade fade fade fade fade fade fade fade_TYPEDEF fade fade_TYPEDEF fade fade fadeSalvar fade fade fade fade fade fade fade fade fade оч fade.Enums fade fade оч fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade оч оч fade fade fade fade fade fade.Enums fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade.Enums fade fade.Enums_Checked_TYPEDEF fade.Enums_CheckedSalvar fade fade fade fade fade fade fade ::: fade.Enums fade fade fade fade fade fade.Enums fade.Enums fade fade fade fade fade fade_Checked fade fade fade fade fade fade fade fade fade fade fade.Enums fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade.Enums fade fade fade fade fade fade fade fade fade fade fade fade fade оч fade fade оч fade fade fade fade fade fade fade fade оч fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fadeSalvar fade fade fade fade fade fade fade fade fade fade fade fade fade.Enums fade fade fade fade fade fade fade fade оч оч fade fade.Enums fade fade ::: fade fade fade fade fade fade оч fade_Checked fade fade fade fade fade fade fade.Enums fade fade fade fade fade fade_Checked fade fade fade fade fade fade оч fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade ::: fade fade fade fade fade fade fade fade fade fade fade оч fade_Checked AsyncStorage fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade_Checked fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade_Checked fade.Enums fade fade fade fade fade fade fade fade fade fadeSalvar fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade.Enums_TYPEDEF fade fade fade fade fade fade fade fade fade fade оч fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade оч fade fade fade fade fade fade fade fade fade fade fade fade fade.Enums ::: fade fade fade fade fade fade fade.Enums fade fade fade fade fade fadeSalvar оч fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fadeSalvar fade fade fade fade fadeSalvar fade fade fade fade fade fade fade fade fade fade оч fade fade Bai.Enums fade fade fade fade fade fade fade fade fade fade.Enums fade fade fade очSalvar fade fade fade fade fade fade fade_Checked fade fade fade fade fade fade fade оч fade fade fade fade fade fade fade fade :::_Checked ::: fade fade fade fade fade fade fade fade Bai fade fade оч fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fadeSalvar fade fade fade fade fade fade fade fade fadeSalvar fade fade fade fade fade fade fade.Enums fade fade fade fade fade fade fade fade ::: fade_Checked fade fade fade fade fade fade fade fade fade fade fade.Enums fade fade fade fade fade fade fade fade fade fade fade.Enums fade fade оч fade.Enums fade оч fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade оч.Enums ::: fade fade fade fade fade fade fade fade fade.Enums fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade.Enums fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade оч fade fade fade fade fade fade fade fade fade fade fade fade fade оч fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade оч fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade оч оч fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fadeSalvar fade fade fade fade fade fade fade fade fade fade fade fade_TYPEDEF fade оч fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade.Enums fade fade fade fade ::: fade fade fade fade fade fade fade fade fade fade fade fade fade.Enums fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade_TYPEDEF fade fade fade fadeSalvar.Enums fade fade ::: fade fade fade fade оч fade fadeSalvar fade fade fade ::: fade fade fade fade fade fade fade fade fade fade fade fade fade fadedl fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade.Enums fade fade fade оч fade fade fade fade fade fade fade fade fade fade fade оч fade fade fade fade fade fade fade fade fade ::: fade fade fade fade fade fade fade fade Bai fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade fade.Enums fade fade fade fade fade fade fade fade fade fade fadeSalvar fade fade fade fade fade fade fade fade fade fade fade fade fade оч fade fade fade fade fade fade fade fade fade fade fade fade fade_TYPEDEF fade fade fade fade fade оч fade fade fade fade fade fade fade.Enums fade fade fade fade fade fade fade fade fade + * [AUTO-TRANSLATED:bd07d170] */ TaskExecutor(uint64_t max_size = 32, uint64_t max_usec = 2 * 1000 * 1000); ~TaskExecutor() = default; diff --git a/src/Thread/TaskQueue.h b/src/Thread/TaskQueue.h index 584e05abe..edd6e56eb 100644 --- a/src/Thread/TaskQueue.h +++ b/src/Thread/TaskQueue.h @@ -17,11 +17,13 @@ namespace toolkit { -//实现了一个基于函数对象的任务列队,该列队是线程安全的,任务列队任务数由信号量控制 +//实现了一个基于函数对象的任务列队,该列队是线程安全的,任务列队任务数由信号量控制 [AUTO-TRANSLATED:67e02e93] +//Implemented a task queue based on function objects, which is thread-safe, and the number of tasks in the task queue is controlled by a semaphore template class TaskQueue { public: - //打入任务至列队 + //打入任务至列队 [AUTO-TRANSLATED:d08b5817] + //Put a task into the queue template void push_task(C &&task_func) { { @@ -40,12 +42,14 @@ class TaskQueue { _sem.post(); } - //清空任务列队 + //清空任务列队 [AUTO-TRANSLATED:dbcd7fe9] + //Clear the task queue void push_exit(size_t n) { _sem.post(n); } - //从列队获取一个任务,由执行线程执行 + //从列队获取一个任务,由执行线程执行 [AUTO-TRANSLATED:4a1143ae] + //Get a task from the queue and execute it by the executing thread bool get_task(T &tsk) { _sem.wait(); std::lock_guard lock(_mutex); diff --git a/src/Thread/ThreadPool.h b/src/Thread/ThreadPool.h index cab7996c1..ca14b6cc4 100644 --- a/src/Thread/ThreadPool.h +++ b/src/Thread/ThreadPool.h @@ -51,7 +51,8 @@ class ThreadPool : public TaskExecutor { wait(); } - //把任务打入线程池并异步执行 + //把任务打入线程池并异步执行 [AUTO-TRANSLATED:651c8d5a] + //Put the task into the thread pool and execute it asynchronously Task::Ptr async(TaskIn task, bool may_sync = true) override { if (may_sync && _thread_group.is_this_thread_in()) { task(); @@ -122,7 +123,8 @@ class ThreadPool : public TaskExecutor { while (true) { startSleep(); if (!_queue.get_task(task)) { - //空任务,退出线程 + //空任务,退出线程 [AUTO-TRANSLATED:583e2f11] + //Empty task, exit the thread break; } sleepWakeUp(); diff --git a/src/Thread/WorkThreadPool.cpp b/src/Thread/WorkThreadPool.cpp index ec50edb97..a63202568 100644 --- a/src/Thread/WorkThreadPool.cpp +++ b/src/Thread/WorkThreadPool.cpp @@ -26,7 +26,8 @@ EventPoller::Ptr WorkThreadPool::getPoller() { } WorkThreadPool::WorkThreadPool() { - //最低优先级 + //最低优先级 [AUTO-TRANSLATED:cd1f0dbc] + //Lowest priority addPoller("work poller", s_pool_size, ThreadPool::PRIORITY_LOWEST, false, s_enable_cpu_affinity); } diff --git a/src/Thread/WorkThreadPool.h b/src/Thread/WorkThreadPool.h index ae7f0a6ac..042472364 100644 --- a/src/Thread/WorkThreadPool.h +++ b/src/Thread/WorkThreadPool.h @@ -24,6 +24,9 @@ class WorkThreadPool : public std::enable_shared_from_this, publ /** * 获取单例 + * Get the singleton instance + + * [AUTO-TRANSLATED:c8852589] */ static WorkThreadPool &Instance(); @@ -31,17 +34,29 @@ class WorkThreadPool : public std::enable_shared_from_this, publ * 设置EventPoller个数,在WorkThreadPool单例创建前有效 * 在不调用此方法的情况下,默认创建thread::hardware_concurrency()个EventPoller实例 * @param size EventPoller个数,如果为0则为thread::hardware_concurrency() + * Set the number of EventPoller instances, effective before the WorkThreadPool singleton is created + * If this method is not called, the default is to create thread::hardware_concurrency() EventPoller instances + * @param size The number of EventPoller instances, if 0 then use thread::hardware_concurrency() + + * [AUTO-TRANSLATED:bb236d87] */ static void setPoolSize(size_t size = 0); /** * 内部创建线程是否设置cpu亲和性,默认设置cpu亲和性 + * Whether to set CPU affinity when creating internal threads, CPU affinity is set by default + + * [AUTO-TRANSLATED:46941c9f] */ static void enableCpuAffinity(bool enable); /** * 获取第一个实例 * @return + * Get the first instance + * @return + + * [AUTO-TRANSLATED:a76aad3b] */ EventPoller::Ptr getFirstPoller(); @@ -50,6 +65,12 @@ class WorkThreadPool : public std::enable_shared_from_this, publ * 如果优先返回当前线程,那么会返回当前线程 * 返回当前线程的目的是为了提高线程安全性 * @return + * Get a lightly loaded instance based on the load situation + * If priority is given to the current thread, it will return the current thread + * The purpose of returning the current thread is to improve thread safety + * @return + + * [AUTO-TRANSLATED:1282b772] */ EventPoller::Ptr getPoller(); diff --git a/src/Thread/semaphore.h b/src/Thread/semaphore.h index 46f31552a..221b14e99 100644 --- a/src/Thread/semaphore.h +++ b/src/Thread/semaphore.h @@ -18,6 +18,15 @@ #include #define HAVE_SEM #endif //HAVE_SEM + /* + * Currently, it is found that semaphores have issues on 32-bit systems, + * sleeping threads cannot be normally woken up, disable them for now + #if defined(__linux__) + #include + #define HAVE_SEM + #endif //HAVE_SEM + + * [AUTO-TRANSLATED:8823f395] */ #include diff --git a/src/Util/CMD.cpp b/src/Util/CMD.cpp index 44e8337f4..3d810a45a 100644 --- a/src/Util/CMD.cpp +++ b/src/Util/CMD.cpp @@ -21,7 +21,8 @@ using namespace std; namespace toolkit { -//默认注册exit/quit/help/clear命令 +//默认注册exit/quit/help/clear命令 [AUTO-TRANSLATED:1411f05e] +//Default registration of exit/quit/help/clear commands static onceToken s_token([]() { REGIST_CMD(exit) REGIST_CMD(quit) @@ -75,7 +76,8 @@ void OptionParser::operator()(mINI &all_args, int argc, char *argv[], const std: stringstream ss; ss << " 未识别的选项,输入\"-h\"获取帮助."; if (index < 0xFF) { - //短参数 + //短参数 [AUTO-TRANSLATED:87b4c1df] + //Short parameters auto it = _map_char_index.find(index); if (it == _map_char_index.end()) { throw std::invalid_argument(ss.str()); @@ -96,7 +98,8 @@ void OptionParser::operator()(mINI &all_args, int argc, char *argv[], const std: } for (auto &pr : _map_options) { if (pr.second._default_value && all_args.find(pr.second._long_opt) == all_args.end()) { - //有默认值,赋值默认值 + //有默认值,赋值默认值 [AUTO-TRANSLATED:9a82f49c] + //Has default value, assigns default value all_args.emplace(pr.second._long_opt, *pr.second._default_value); } } diff --git a/src/Util/File.cpp b/src/Util/File.cpp index d1a291b4d..f08fac661 100755 --- a/src/Util/File.cpp +++ b/src/Util/File.cpp @@ -71,7 +71,8 @@ struct dirent *readdir(DIR *d) { dir->d_type = 1; } if (d->index) { - //覆盖前释放内存 + //覆盖前释放内存 [AUTO-TRANSLATED:1cb478a1] + //Release memory before covering free(d->index); d->index = nullptr; } @@ -83,12 +84,14 @@ int closedir(DIR *d) { if (!d) { return -1; } - //关闭句柄 + //关闭句柄 [AUTO-TRANSLATED:ec4f562d] + //Close handle if (d->handle != INVALID_HANDLE_VALUE) { FindClose(d->handle); d->handle = INVALID_HANDLE_VALUE; } - //释放内存 + //释放内存 [AUTO-TRANSLATED:0f4046dc] + //Release memory if (d->index) { free(d->index); d->index = nullptr; @@ -144,7 +147,8 @@ bool File::create_path(const std::string &file, unsigned int mod) { return true; } -//判断是否为目录 +//判断是否为目录 [AUTO-TRANSLATED:639e15fa] +//Determine if it is a directory bool File::is_dir(const std::string &path) { auto dir = opendir(path.data()); if (!dir) { @@ -154,7 +158,8 @@ bool File::is_dir(const std::string &path) { return true; } -//判断是否为常规文件 +//判断是否为常规文件 [AUTO-TRANSLATED:59e6b610] +//Determine if it is a regular file bool File::fileExist(const std::string &path) { auto fp = fopen(path.data(), "rb"); if (!fp) { @@ -164,7 +169,8 @@ bool File::fileExist(const std::string &path) { return true; } -//判断是否是特殊目录 +//判断是否是特殊目录 [AUTO-TRANSLATED:cda5ed9f] +//Determine if it is a special directory bool File::is_special_dir(const std::string &path) { return path == "." || path == ".."; } @@ -243,9 +249,11 @@ string File::parentDir(const std::string &path) { string File::absolutePath(const std::string &path, const std::string ¤t_path, bool can_access_parent) { string currentPath = current_path; if (!currentPath.empty()) { - //当前目录不为空 + //当前目录不为空 [AUTO-TRANSLATED:5bf272ae] + //Current directory is not empty if (currentPath.front() == '.') { - //如果当前目录是相对路径,那么先转换成绝对路径 + //如果当前目录是相对路径,那么先转换成绝对路径 [AUTO-TRANSLATED:3cc6469e] + //If the current directory is a relative path, convert it to an absolute path first currentPath = absolutePath(current_path, exeDir(), true); } } else { @@ -253,25 +261,30 @@ string File::absolutePath(const std::string &path, const std::string ¤t_pa } if (path.empty()) { - //相对路径为空,那么返回当前目录 + //相对路径为空,那么返回当前目录 [AUTO-TRANSLATED:6dd21c11] + //Relative path is empty, return the current directory return currentPath; } if (currentPath.back() != '/') { - //确保当前目录最后字节为'/' + //确保当前目录最后字节为'/' [AUTO-TRANSLATED:fc83fcfe] + //Ensure the last byte of the current directory is '/ currentPath.push_back('/'); } auto rootPath = currentPath; auto dir_vec = split(path, "/"); for (auto &dir : dir_vec) { if (dir.empty() || dir == ".") { - //忽略空或本文件夹 + //忽略空或本文件夹 [AUTO-TRANSLATED:3dd69d88] + //Ignore empty or current folder continue; } if (dir == "..") { - //访问上级目录 + //访问上级目录 [AUTO-TRANSLATED:d3c0b980] + //Access parent directory if (!can_access_parent && currentPath.size() <= rootPath.size()) { - //不能访问根目录之外的目录, 返回根目录 + //不能访问根目录之外的目录, 返回根目录 [AUTO-TRANSLATED:9d79ec25] + //Cannot access directories outside the root, return to root return rootPath; } currentPath = parentDir(currentPath); @@ -282,7 +295,8 @@ string File::absolutePath(const std::string &path, const std::string ¤t_pa } if (path.back() != '/' && currentPath.back() == '/') { - //在路径是文件的情况下,防止转换成目录 + //在路径是文件的情况下,防止转换成目录 [AUTO-TRANSLATED:db91e611] + //Prevent conversion to directory when path is a file currentPath.pop_back(); } return currentPath; @@ -298,7 +312,8 @@ void File::scanDir(const std::string &path_in, const functiond_name[0] == '.') { - //隐藏的文件 + //隐藏的文件 [AUTO-TRANSLATED:3b2eb642] + //Hidden file continue; } string strAbsolutePath = path + "/" + pDirent->d_name; bool isDir = is_dir(strAbsolutePath); if (!cb(strAbsolutePath, isDir)) { - //不再继续扫描 + //不再继续扫描 [AUTO-TRANSLATED:991bdb3f] + //Stop scanning break; } if (isDir && enter_subdirectory) { - //如果是文件夹并且扫描子文件夹,那么递归扫描 + //如果是文件夹并且扫描子文件夹,那么递归扫描 [AUTO-TRANSLATED:36773722] + //If it's a folder and scanning subfolders, then recursively scan scanDir(strAbsolutePath, cb, enter_subdirectory); } } @@ -354,7 +372,8 @@ static bool isEmptyDir(const std::string &path) { void File::deleteEmptyDir(const std::string &dir, bool backtrace) { if (!File::is_dir(dir) || !isEmptyDir(dir)) { - // 不是文件夹或者非空 + // 不是文件夹或者非空 [AUTO-TRANSLATED:fad1712d] + //Not a folder or not empty return; } File::delete_file(dir); diff --git a/src/Util/File.h b/src/Util/File.h index 4d7815593..419b10532 100644 --- a/src/Util/File.h +++ b/src/Util/File.h @@ -64,28 +64,39 @@ namespace toolkit { class File { public: - //创建路径 + //创建路径 [AUTO-TRANSLATED:419b36b7] + //Create path static bool create_path(const std::string &file, unsigned int mod); - //新建文件,目录文件夹自动生成 + //新建文件,目录文件夹自动生成 [AUTO-TRANSLATED:e605efe8] + //Create a new file, and the directory folder will be generated automatically static FILE *create_file(const std::string &file, const std::string &mode); - //判断是否为目录 + //判断是否为目录 [AUTO-TRANSLATED:639e15fa] + //Determine if it is a directory static bool is_dir(const std::string &path); - //判断是否是特殊目录(. or ..) + //判断是否是特殊目录(. or ..) [AUTO-TRANSLATED:f61f7e33] + //Determine if it is a special directory (. or ..) static bool is_special_dir(const std::string &path); - //删除目录或文件 + //删除目录或文件 [AUTO-TRANSLATED:79bed783] + //Delete a directory or file static int delete_file(const std::string &path, bool del_empty_dir = false, bool backtrace = true); - //判断文件是否存在 + //判断文件是否存在 [AUTO-TRANSLATED:edf3cf49] + //Determine if a file exists static bool fileExist(const std::string &path); /** * 加载文件内容至string * @param path 加载的文件路径 * @return 文件内容 + * Load file content to string + * @param path The path of the file to load + * @return The file content + + * [AUTO-TRANSLATED:c2f0e9fa] */ static std::string loadFile(const std::string &path); @@ -94,6 +105,12 @@ class File { * @param data 文件内容 * @param path 保存的文件路径 * @return 是否保存成功 + * Save content to file + * @param data The file content + * @param path The path to save the file + * @return Whether the save was successful + + * [AUTO-TRANSLATED:a919ad75] */ static bool saveFile(const std::string &data, const std::string &path); @@ -101,6 +118,11 @@ class File { * 获取父文件夹 * @param path 路径 * @return 文件夹 + * Get the parent folder + * @param path The path + * @return The folder + + * [AUTO-TRANSLATED:3a584db5] */ static std::string parentDir(const std::string &path); @@ -110,6 +132,13 @@ class File { * @param current_path 当前目录 * @param can_access_parent 能否访问父目录之外的目录 * @return 替换"../"之后的路径 + * Replace "../" and get the absolute path + * @param path The relative path, which may contain "../" + * @param current_path The current directory + * @param can_access_parent Whether it can access directories outside the parent directory + * @return The path after replacing "../" + + * [AUTO-TRANSLATED:45686bfc] */ static std::string absolutePath(const std::string &path, const std::string ¤t_path, bool can_access_parent = false); @@ -119,6 +148,13 @@ class File { * @param cb 回调对象 ,path为绝对路径,isDir为该路径是否为文件夹,返回true代表继续扫描,否则中断 * @param enter_subdirectory 是否进入子目录扫描 * @param show_hidden_file 是否显示隐藏的文件 + * Traverse all files under the folder + * @param path Folder path + * @param cb Callback object, path is the absolute path, isDir indicates whether the path is a folder, returns true to continue scanning, otherwise stops + * @param enter_subdirectory Whether to enter subdirectory scanning + * @param show_hidden_file Whether to display hidden files + + * [AUTO-TRANSLATED:e97ab081] */ static void scanDir(const std::string &path, const std::function &cb, bool enter_subdirectory = false, bool show_hidden_file = false); @@ -127,6 +163,11 @@ class File { * 获取文件大小 * @param fp 文件句柄 * @param remain_size true:获取文件剩余未读数据大小,false:获取文件总大小 + * Get file size + * @param fp File handle + * @param remain_size true: Get the remaining unread data size of the file, false: Get the total file size + + * [AUTO-TRANSLATED:9abfdae9] */ static uint64_t fileSize(FILE *fp, bool remain_size = false); @@ -135,6 +176,12 @@ class File { * @param path 文件路径 * @return 文件大小 * @warning 调用者应确保文件存在 + * Get file size + * @param path File path + * @return File size + * @warning The caller should ensure the file exists + + * [AUTO-TRANSLATED:6985b813] */ static uint64_t fileSize(const std::string &path); @@ -142,6 +189,11 @@ class File { * 尝试删除空文件夹 * @param dir 文件夹路径 * @param backtrace 是否回溯上层文件夹,上层文件夹为空也一并删除,以此类推 + * Attempt to delete an empty folder + * @param dir Folder path + * @param backtrace Whether to backtrack to the upper-level folder, if the upper-level folder is empty, it will also be deleted, and so on + + * [AUTO-TRANSLATED:a1780506] */ static void deleteEmptyDir(const std::string &dir, bool backtrace = true); diff --git a/src/Util/NoticeCenter.h b/src/Util/NoticeCenter.h index c14a3dd52..ffdc4b9d2 100644 --- a/src/Util/NoticeCenter.h +++ b/src/Util/NoticeCenter.h @@ -46,7 +46,8 @@ class EventDispatcher { using stl_func = std::function(args))...)>; decltype(_mapListener) copy; { - // 先拷贝(开销比较小),目的是防止在触发回调时还是上锁状态从而导致交叉互锁 + // 先拷贝(开销比较小),目的是防止在触发回调时还是上锁状态从而导致交叉互锁 [AUTO-TRANSLATED:62bff466] + //First copy (lower overhead), to prevent cross-locking when triggering callbacks while still locked std::lock_guard lck(_mtxListener); copy = _mapListener; } @@ -108,7 +109,8 @@ class NoticeCenter : public std::enable_shared_from_this { void delListener(void *tag, const std::string &event) { auto dispatcher = getDispatcher(event); if (!dispatcher) { - // 不存在该事件 + // 不存在该事件 [AUTO-TRANSLATED:d9014749] + //This event does not exist return; } bool empty; @@ -118,7 +120,8 @@ class NoticeCenter : public std::enable_shared_from_this { } } - // 这个方法性能比较差 + // 这个方法性能比较差 [AUTO-TRANSLATED:71ea304b] + //This method has poor performance void delListener(void *tag) { std::lock_guard lck(_mtxListener); bool empty; @@ -142,7 +145,8 @@ class NoticeCenter : public std::enable_shared_from_this { int emitEvent_l(bool safe, const std::string &event, ArgsType &&...args) { auto dispatcher = getDispatcher(event); if (!dispatcher) { - // 该事件无人监听 + // 该事件无人监听 [AUTO-TRANSLATED:9196cf42] + //No one is listening to this event return 0; } return dispatcher->emitEvent(safe, std::forward(args)...); @@ -155,7 +159,8 @@ class NoticeCenter : public std::enable_shared_from_this { return it->second; } if (create) { - // 如果为空则创建一个 + // 如果为空则创建一个 [AUTO-TRANSLATED:8412a9ae] + //Create one if it is empty EventDispatcher::Ptr dispatcher(new EventDispatcher()); _mapListener.emplace(event, dispatcher); return dispatcher; @@ -167,7 +172,8 @@ class NoticeCenter : public std::enable_shared_from_this { std::lock_guard lck(_mtxListener); auto it = _mapListener.find(event); if (it != _mapListener.end() && dispatcher == it->second) { - // 两者相同则删除 + // 两者相同则删除 [AUTO-TRANSLATED:8d84179d] + //If both are the same, delete it _mapListener.erase(it); } } diff --git a/src/Util/ResourcePool.h b/src/Util/ResourcePool.h index 8731c03cb..73a98b398 100644 --- a/src/Util/ResourcePool.h +++ b/src/Util/ResourcePool.h @@ -41,6 +41,12 @@ class shared_ptr_imp : public std::shared_ptr { * @param ptr 裸指针 * @param weakPool 管理本指针的循环池 * @param quit 对接是否放弃循环使用 + * Constructs a smart pointer + * @param ptr Raw pointer + * @param weakPool Circular pool managing this pointer + * @param quit Whether to give up circular reuse + + * [AUTO-TRANSLATED:5af6d6a5] */ shared_ptr_imp( C *ptr, const std::weak_ptr> &weakPool, std::shared_ptr quit, @@ -49,6 +55,10 @@ class shared_ptr_imp : public std::shared_ptr { /** * 放弃或恢复回到循环池继续使用 * @param flag + * Abandon or recover to continue using in the circular pool + * @param flag + + * [AUTO-TRANSLATED:eda3e499] */ void quit(bool flag = true) { if (_quit) { @@ -98,7 +108,8 @@ class ResourcePool_l : public std::enable_shared_from_this> { return std::shared_ptr(getPtr(), [weak_self](C *ptr) { auto strongPool = weak_self.lock(); if (strongPool) { - //放入循环池 + //放入循环池 [AUTO-TRANSLATED:5ec73a78] + //Put into circular pool strongPool->recycle(ptr); } else { delete ptr; @@ -110,7 +121,8 @@ class ResourcePool_l : public std::enable_shared_from_this> { void recycle(C *obj) { auto is_busy = _busy.test_and_set(); if (!is_busy) { - //获取到锁 + //获取到锁 [AUTO-TRANSLATED:6eb7c6e9] + //Acquired lock if (_objs.size() >= _pool_size) { delete obj; } else { @@ -118,7 +130,8 @@ class ResourcePool_l : public std::enable_shared_from_this> { } _busy.clear(); } else { - //未获取到锁 + //未获取到锁 [AUTO-TRANSLATED:2b5e8adb] + //Failed to acquire lock delete obj; } } @@ -127,7 +140,8 @@ class ResourcePool_l : public std::enable_shared_from_this> { C *ptr; auto is_busy = _busy.test_and_set(); if (!is_busy) { - //获取到锁 + //获取到锁 [AUTO-TRANSLATED:6eb7c6e9] + //Acquired lock if (_objs.size() == 0) { ptr = _alloc(); } else { @@ -136,7 +150,8 @@ class ResourcePool_l : public std::enable_shared_from_this> { } _busy.clear(); } else { - //未获取到锁 + //未获取到锁 [AUTO-TRANSLATED:2b5e8adb] + //Failed to acquire lock ptr = _alloc(); } return ptr; @@ -155,6 +170,10 @@ class ResourcePool_l : public std::enable_shared_from_this> { /** * 循环池,注意,循环池里面的对象不能继承enable_shared_from_this! * @tparam C + * Circular pool, note that objects in the circular pool cannot inherit from enable_shared_from_this! + * @tparam C + + * [AUTO-TRANSLATED:e08caac8] */ template class ResourcePool { @@ -173,10 +192,12 @@ class ResourcePool { #endif // defined(SUPPORT_DYNAMIC_TEMPLATE) void setSize(size_t size) { pool->setSize(size); } - //获取一个对象,性能差些,但是功能丰富些 + //获取一个对象,性能差些,但是功能丰富些 [AUTO-TRANSLATED:88b9a207] + //Get an object, performance is slightly worse, but with more features ValuePtr obtain(const std::function &on_recycle = nullptr) { return pool->obtain(on_recycle); } - //获取一个对象,性能好些 + //获取一个对象,性能好些 [AUTO-TRANSLATED:0032c7ca] + //Get an object, performance is slightly better std::shared_ptr obtain2() { return pool->obtain2(); } private: @@ -194,7 +215,8 @@ shared_ptr_imp::shared_ptr_imp(C *ptr, } auto strongPool = weakPool.lock(); if (strongPool && !(*quit)) { - //循环池还在并且不放弃放入循环池 + //循环池还在并且不放弃放入循环池 [AUTO-TRANSLATED:96e856da] + //Loop pool is still in and does not give up putting into loop pool strongPool->recycle(ptr); } else { delete ptr; diff --git a/src/Util/RingBuffer.h b/src/Util/RingBuffer.h index 0474f46dd..9ad6fb9ac 100644 --- a/src/Util/RingBuffer.h +++ b/src/Util/RingBuffer.h @@ -22,7 +22,8 @@ #include "List.h" #include "Poller/EventPoller.h" -// GOP缓存最大长度下限值 +// GOP缓存最大长度下限值 [AUTO-TRANSLATED:63162058] +//GOP cache minimum length lower bound value #define RING_MIN_SIZE 32 #define LOCK_GUARD(mtx) std::lock_guard lck(mtx) @@ -48,6 +49,12 @@ class _RingReaderDispatcher; * 该对象的事件触发都会在绑定的poller线程中执行 * 所以把锁去掉了 * 对该对象的一切操作都应该在poller线程中执行 + * Circular cache reader + * All events triggered by this object will be executed in the bound poller thread + * So the lock is removed + * All operations on this object should be executed in the poller thread + + * [AUTO-TRANSLATED:3d0f773d] */ template class _RingReader { @@ -115,7 +122,8 @@ class _RingStorage { using Ptr = std::shared_ptr<_RingStorage>; using GopType = List>>; _RingStorage(size_t max_size, size_t max_gop_size) { - // gop缓存个数不能小于32 + // gop缓存个数不能小于32 [AUTO-TRANSLATED:63d52404] + //The number of GOP caches cannot be less than 32 if (max_size < RING_MIN_SIZE) { max_size = RING_MIN_SIZE; } @@ -131,34 +139,46 @@ class _RingStorage { * @param in 数据 * @param is_key 是否为关键帧 * @return 是否触发重置环形缓存大小 + * Write data to the circular cache + * @param in Data + * @param is_key Whether it is a key frame + * @return Whether to trigger a reset of the circular cache size + + * [AUTO-TRANSLATED:8ccedd1d] */ void write(T in, bool is_key = true) { if (is_key) { _have_idr = true; _started = true; if (!_data_cache.back().empty()) { - //当前gop列队还没收到任意缓存 + //当前gop列队还没收到任意缓存 [AUTO-TRANSLATED:81e257d0] + //The current GOP queue has not received any cache _data_cache.emplace_back(); } if (_data_cache.size() > _max_gop_size) { - // GOP个数超过限制,那么移除最早的GOP + // GOP个数超过限制,那么移除最早的GOP [AUTO-TRANSLATED:054ad5e4] + //The number of GOPs exceeds the limit, so remove the earliest GOP popFrontGop(); } } if (!_have_idr && _started) { - //缓存中没有关键帧,那么gop缓存无效 + //缓存中没有关键帧,那么gop缓存无效 [AUTO-TRANSLATED:394a9170] + //There is no key frame in the cache, so the GOP cache is invalid return; } _data_cache.back().emplace_back(std::make_pair(is_key, std::move(in))); if (++_size > _max_size) { - // GOP缓存溢出 + // GOP缓存溢出 [AUTO-TRANSLATED:1cd0ddc4] + //GOP cache overflow while (_data_cache.size() > 1) { - //先尝试清除老的GOP缓存 + //先尝试清除老的GOP缓存 [AUTO-TRANSLATED:a01422a1] + //Try to clear the old GOP cache first popFrontGop(); } if (_size > _max_size) { - //还是大于最大缓冲限制,那么清空所有GOP + //还是大于最大缓冲限制,那么清空所有GOP [AUTO-TRANSLATED:dec7aa9b] + //Still greater than the maximum buffer limit, so clear all GOPs clearCache(); } } @@ -212,6 +232,10 @@ class RingBuffer; /** * 环形缓存事件派发器,只能一个poller线程操作它 * @tparam T + * Ring buffer event dispatcher, can only be operated by one poller thread + * @tparam T + + * [AUTO-TRANSLATED:6c0d8449] */ template class _RingReaderDispatcher : public std::enable_shared_from_this<_RingReaderDispatcher> { @@ -340,7 +364,8 @@ class RingBuffer : public std::enable_shared_from_this> { RingBuffer(size_t max_size = 1024, onReaderChanged cb = nullptr, size_t max_gop_size = 1) { _storage = std::make_shared(max_size, max_gop_size); _on_reader_changed = cb ? std::move(cb) : [](int size) {}; - //先触发无人观看 + //先触发无人观看 [AUTO-TRANSLATED:34c64fef] + //First trigger no one watching _on_reader_changed(0); } @@ -355,7 +380,8 @@ class RingBuffer : public std::enable_shared_from_this> { LOCK_GUARD(_mtx_map); for (auto &pr : _dispatcher_map) { auto &second = pr.second; - //切换线程后触发onRead事件 + //切换线程后触发onRead事件 [AUTO-TRANSLATED:4ca6647d] + //Switch thread and trigger onRead event pr.first->async([second, in, is_key]() mutable { second->write(std::move(in), is_key); }, false); } _storage->write(std::move(in), is_key); @@ -365,7 +391,8 @@ class RingBuffer : public std::enable_shared_from_this> { LOCK_GUARD(_mtx_map); for (auto &pr : _dispatcher_map) { auto &second = pr.second; - // 切换线程后触发sendMessage + // 切换线程后触发sendMessage [AUTO-TRANSLATED:350138c9] + //Switch thread and trigger sendMessage pr.first->async([second, data]() { second->sendMessage(data); }, false); } } @@ -400,7 +427,8 @@ class RingBuffer : public std::enable_shared_from_this> { _storage->clearCache(); for (auto &pr : _dispatcher_map) { auto &second = pr.second; - //切换线程后清空缓存 + //切换线程后清空缓存 [AUTO-TRANSLATED:150f7fa4] + //Switch thread and clear cache pr.first->async([second]() { second->clearCache(); }, false); } } @@ -416,10 +444,12 @@ class RingBuffer : public std::enable_shared_from_this> { LOCK_GUARD(_mtx_map); auto info_vec = std::make_shared>>(); - // 1、最少确保一个元素 + // 1、最少确保一个元素 [AUTO-TRANSLATED:6dafe078] + //1. Ensure at least one element info_vec->resize(_dispatcher_map.empty() ? 1 : _dispatcher_map.size()); std::shared_ptr on_finished(nullptr, [cb, info_vec](void *) mutable { - // 2、防止这里为空 + // 2、防止这里为空 [AUTO-TRANSLATED:4484baf7] + //2. Prevent this from being empty auto &lst = *info_vec->begin(); for (auto &item : *info_vec) { if (&lst != &item) { diff --git a/src/Util/SSLBox.cpp b/src/Util/SSLBox.cpp index a82348204..1362578fd 100644 --- a/src/Util/SSLBox.cpp +++ b/src/Util/SSLBox.cpp @@ -23,7 +23,8 @@ #endif //defined(ENABLE_OPENSSL) #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME -//openssl版本是否支持sni +//openssl版本是否支持sni [AUTO-TRANSLATED:4c92a880] +//Is the OpenSSL version SNI supported #define SSL_ENABLE_SNI #endif @@ -121,22 +122,26 @@ int SSL_Initor::findCertificate(SSL *ssl, int *, void *arg) { const char *vhost = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name); if (vhost && vhost[0] != '\0') { - //根据域名找到证书 + //根据域名找到证书 [AUTO-TRANSLATED:783a55d8] + //Find the certificate based on the domain name ctx = ref.getSSLCtx(vhost, (bool) (arg)).get(); if (!ctx) { - //未找到对应的证书 + //未找到对应的证书 [AUTO-TRANSLATED:d4550e6f] + //No corresponding certificate found WarnL << "Can not find any certificate of host: " << vhost << ", select default certificate of: " << ref._default_vhost[(bool) (arg)]; } } if (!ctx) { - //客户端未指定域名或者指定的证书不存在,那么选择一个默认的证书 + //客户端未指定域名或者指定的证书不存在,那么选择一个默认的证书 [AUTO-TRANSLATED:35115b5c] + //The client did not specify a domain name or the specified certificate does not exist, so a default certificate is selected ctx = ref.getSSLCtx("", (bool) (arg)).get(); } if (!ctx) { - //未有任何有效的证书 + //未有任何有效的证书 [AUTO-TRANSLATED:e1d7f5b7] + //No valid certificate available WarnL << "Can not find any available certificate of host: " << (vhost ? vhost : "default host") << ", tls handshake failed"; return SSL_TLSEXT_ERR_ALERT_FATAL; @@ -168,7 +173,8 @@ bool SSL_Initor::setContext(const string &vhost, const shared_ptr &ctx, _default_vhost[server_mode] = vhost; } if (vhost.find("*.") == 0) { - //通配符证书 + //通配符证书 [AUTO-TRANSLATED:faeefee7] + //Wildcard certificate _ctxs_wildcards[server_mode][vhost.substr(1)] = ctx; } DebugL << "Add certificate of: " << vhost; @@ -182,7 +188,8 @@ bool SSL_Initor::setContext(const string &vhost, const shared_ptr &ctx, void SSL_Initor::setupCtx(SSL_CTX *ctx) { #if defined(ENABLE_OPENSSL) - //加载默认信任证书 + //加载默认信任证书 [AUTO-TRANSLATED:4d98f092] + //Load default trusted certificate SSLUtil::loadDefaultCAs(ctx); SSL_CTX_set_cipher_list(ctx, "ALL:!ADH:!LOW:!EXP:!MD5:!3DES:!DES:!IDEA:!RC4:@STRENGTH"); SSL_CTX_set_verify_depth(ctx, 9); @@ -235,10 +242,12 @@ void SSL_Initor::setupCtx(SSL_CTX *ctx) { shared_ptr SSL_Initor::makeSSL(bool server_mode) { #if defined(ENABLE_OPENSSL) #ifdef SSL_ENABLE_SNI - //openssl 版本支持SNI + //openssl 版本支持SNI [AUTO-TRANSLATED:b8029f6c] + //OpenSSL version supports SNI return SSLUtil::makeSSL(_ctx_empty[server_mode].get()); #else - //openssl 版本不支持SNI,选择默认证书 + //openssl 版本不支持SNI,选择默认证书 [AUTO-TRANSLATED:cedb5f02] + //OpenSSL version does not support SNI, select default certificate return SSLUtil::makeSSL(getSSLCtx("",server_mode).get()); #endif//SSL_CTRL_SET_TLSEXT_HOSTNAME #else @@ -282,14 +291,16 @@ std::shared_ptr SSL_Initor::getSSLCtx_l(const string &vhost_in, bool se if (!_default_vhost[server_mode].empty()) { vhost = _default_vhost[server_mode]; } else { - //没默认主机,选择空主机 + //没默认主机,选择空主机 [AUTO-TRANSLATED:99a7d8d4] + //No default host, select empty host if (server_mode) { WarnL << "Server with ssl must have certification and key"; } return _ctx_empty[server_mode]; } } - //根据主机名查找证书 + //根据主机名查找证书 [AUTO-TRANSLATED:dcc98736] + //Find certificate by hostname auto it = _ctxs[server_mode].find(vhost); if (it == _ctxs[server_mode].end()) { return nullptr; @@ -351,12 +362,14 @@ void SSL_Box::onRecv(const Buffer::Ptr &buffer) { while (offset < buffer->size()) { auto nwrite = BIO_write(_read_bio, buffer->data() + offset, buffer->size() - offset); if (nwrite > 0) { - //部分或全部写入bio完毕 + //部分或全部写入bio完毕 [AUTO-TRANSLATED:baabfef4] + //Partial or full write to bio completed offset += nwrite; flush(); continue; } - //nwrite <= 0,出现异常 + //nwrite <= 0,出现异常 [AUTO-TRANSLATED:986e8f36] + //nwrite <= 0, an error occurred ErrorL << "Ssl error on BIO_write: " << SSLUtil::getLastError(); shutdown(); break; @@ -407,11 +420,13 @@ void SSL_Box::flushWriteBio() { } while (nread > 0 && buf_size - total > 0); if (!total) { - //未有数据 + //未有数据 [AUTO-TRANSLATED:9ae3aaa5] + //No data available return; } - //触发此次回调 + //触发此次回调 [AUTO-TRANSLATED:dc10c264] + //Trigger this callback buffer_bio->data()[total] = '\0'; buffer_bio->setSize(total); if (_on_enc) { @@ -419,7 +434,8 @@ void SSL_Box::flushWriteBio() { } if (nread > 0) { - //还有剩余数据,读取剩余数据 + //还有剩余数据,读取剩余数据 [AUTO-TRANSLATED:008f4187] + //Still have remaining data, read the remaining data flushWriteBio(); } #endif //defined(ENABLE_OPENSSL) @@ -440,11 +456,13 @@ void SSL_Box::flushReadBio() { } while (nread > 0 && buf_size - total > 0); if (!total) { - //未有数据 + //未有数据 [AUTO-TRANSLATED:9ae3aaa5] + //No data available return; } - //触发此次回调 + //触发此次回调 [AUTO-TRANSLATED:dc10c264] + //Trigger this callback buffer_bio->data()[total] = '\0'; buffer_bio->setSize(total); if (_on_dec) { @@ -452,7 +470,8 @@ void SSL_Box::flushReadBio() { } if (nread > 0) { - //还有剩余数据,读取剩余数据 + //还有剩余数据,读取剩余数据 [AUTO-TRANSLATED:008f4187] + //Still have remaining data, read the remaining data flushReadBio(); } #endif //defined(ENABLE_OPENSSL) @@ -471,35 +490,41 @@ void SSL_Box::flush() { flushReadBio(); if (!SSL_is_init_finished(_ssl.get()) || _buffer_send.empty()) { - //ssl未握手结束或没有需要发送的数据 + //ssl未握手结束或没有需要发送的数据 [AUTO-TRANSLATED:39f8490c] + //SSL handshake not finished or no data to send flushWriteBio(); return; } - //加密数据并发送 + //加密数据并发送 [AUTO-TRANSLATED:c09fdbd0] + //Encrypt data and send while (!_buffer_send.empty()) { auto &front = _buffer_send.front(); uint32_t offset = 0; while (offset < front->size()) { auto nwrite = SSL_write(_ssl.get(), front->data() + offset, front->size() - offset); if (nwrite > 0) { - //部分或全部写入完毕 + //部分或全部写入完毕 [AUTO-TRANSLATED:661163d2] + //Partial or complete write finished offset += nwrite; flushWriteBio(); continue; } - //nwrite <= 0,出现异常 + //nwrite <= 0,出现异常 [AUTO-TRANSLATED:986e8f36] + //nwrite <= 0, an exception occurred break; } if (offset != front->size()) { - //这个包未消费完毕,出现了异常,清空数据并断开ssl + //这个包未消费完毕,出现了异常,清空数据并断开ssl [AUTO-TRANSLATED:1823c65a] + //This package has not been fully consumed, an exception occurred, clear data and disconnect ssl ErrorL << "Ssl error on SSL_write: " << SSLUtil::getLastError(); shutdown(); break; } - //这个包消费完毕,开始消费下一个包 + //这个包消费完毕,开始消费下一个包 [AUTO-TRANSLATED:6fa31240] + //This package has been fully consumed, start consuming the next package _buffer_send.pop_front(); } #endif //defined(ENABLE_OPENSSL) diff --git a/src/Util/SSLBox.h b/src/Util/SSLBox.h index 34515b141..f2aeb4cb1 100644 --- a/src/Util/SSLBox.h +++ b/src/Util/SSLBox.h @@ -43,6 +43,16 @@ class SSL_Initor { * @param password 私钥加密密码 * @param is_file 参数pem_or_p12是否为文件路径 * @param is_default 是否为默认证书 + * Load public and private keys from a file or string + * The certificate file must contain both public and private keys (cer format certificates only include public keys, use the following method to load) + * The client can load the certificate by default (unless the server requires the client to provide a certificate) + * @param pem_or_p12 pem or p12 file path or file content string + * @param server_mode Whether it is in server mode + * @param password Private key encryption password + * @param is_file Whether the parameter pem_or_p12 is a file path + * @param is_default Whether it is the default certificate + + * [AUTO-TRANSLATED:18cec755] */ bool loadCertificate(const std::string &pem_or_p12, bool server_mode = true, const std::string &password = "", bool is_file = true, bool is_default = true); @@ -51,6 +61,11 @@ class SSL_Initor { * 是否忽略无效的证书 * 默认忽略,强烈建议不要忽略! * @param ignore 标记 + * Whether to ignore invalid certificates + * Ignore by default, strongly not recommended! + * @param ignore Flag + + * [AUTO-TRANSLATED:fd45125a] */ void ignoreInvalidCertificate(bool ignore = true); @@ -62,6 +77,15 @@ class SSL_Initor { * @param password pem或p12证书的密码 * @param is_file 是否为文件路径 * @return 是否加载成功 + * Trust a certain certificate, generally used for clients to trust self-signed certificates or certificates signed by self-signed CAs + * For example, if my client wants to trust a certificate I issued myself, we can only trust this certificate + * @param pem_p12_cer pem file or p12 file or cer file path or content + * @param server_mode Whether it is in server mode + * @param password pem or p12 certificate password + * @param is_file Whether it is a file path + * @return Whether the loading is successful + + * [AUTO-TRANSLATED:9ace5400] */ bool trustCertificate(const std::string &pem_p12_cer, bool server_mode = false, const std::string &password = "", bool is_file = true); @@ -71,6 +95,12 @@ class SSL_Initor { * @param cer 证书公钥 * @param server_mode 是否为服务模式 * @return 是否加载成功 + * Trust a certain certificate + * @param cer Certificate public key + * @param server_mode Whether it is in server mode + * @return Whether the loading is successful + + * [AUTO-TRANSLATED:557120dd] */ bool trustCertificate(X509 *cer, bool server_mode = false); @@ -79,6 +109,12 @@ class SSL_Initor { * @param vhost 虚拟主机名 * @param server_mode 是否为服务器模式 * @return SSL_CTX对象 + * Get the SSL_CTX object based on the virtual host + * @param vhost Virtual host name + * @param server_mode Whether it is in server mode + * @return SSL_CTX object + + * [AUTO-TRANSLATED:4d771109] */ std::shared_ptr getSSLCtx(const std::string &vhost, bool server_mode); @@ -88,6 +124,9 @@ class SSL_Initor { /** * 创建SSL对象 + * Create an SSL object + + * [AUTO-TRANSLATED:047a0b4c] */ std::shared_ptr makeSSL(bool server_mode); @@ -97,12 +136,23 @@ class SSL_Initor { * @param ctx ssl context * @param server_mode ssl context * @param is_default 是否为默认证书 + * Set the ssl context + * @param vhost Virtual host name + * @param ctx ssl context + * @param server_mode ssl context + * @param is_default Whether it is the default certificate + + * [AUTO-TRANSLATED:265f3049] */ bool setContext(const std::string &vhost, const std::shared_ptr &ctx, bool server_mode, bool is_default = true); /** * 设置SSL_CTX的默认配置 * @param ctx 对象指针 + * Set the default configuration for SSL_CTX + * @param ctx Object pointer + + * [AUTO-TRANSLATED:1b3438d0] */ void setupCtx(SSL_CTX *ctx); @@ -112,11 +162,17 @@ class SSL_Initor { /** * 获取默认的虚拟主机 + * Get the default virtual host + + * [AUTO-TRANSLATED:e2430399] */ std::string defaultVhost(bool server_mode); /** * 完成vhost name 匹配的回调函数 + * Callback function for completing vhost name matching + + * [AUTO-TRANSLATED:f9973cfa] */ static int findCertificate(SSL *ssl, int *ad, void *arg); @@ -145,34 +201,56 @@ class SSL_Box { /** * 收到密文后,调用此函数解密 * @param buffer 收到的密文数据 + * Decrypts the received ciphertext after calling this function + * @param buffer Received ciphertext data + + * [AUTO-TRANSLATED:7e8b1fc6] */ void onRecv(const Buffer::Ptr &buffer); /** * 需要加密明文调用此函数 * @param buffer 需要加密的明文数据 + * Calls this function to encrypt the plaintext that needs to be encrypted + * @param buffer Plaintext data that needs to be encrypted + + * [AUTO-TRANSLATED:9d386695] */ void onSend(Buffer::Ptr buffer); /** * 设置解密后获取明文的回调 * @param cb 回调对象 + * Sets the callback to get the plaintext after decryption + * @param cb Callback object + + * [AUTO-TRANSLATED:897359bc] */ void setOnDecData(const std::function &cb); /** * 设置加密后获取密文的回调 * @param cb 回调对象 + * Sets the callback to get the ciphertext after encryption + * @param cb Callback object + + * [AUTO-TRANSLATED:bb31b34b] */ void setOnEncData(const std::function &cb); /** * 终结ssl + * Terminates SSL + + * [AUTO-TRANSLATED:2ab06469] */ void shutdown(); /** * 清空数据 + * Clears data + + * [AUTO-TRANSLATED:62d4f400] */ void flush(); @@ -180,6 +258,11 @@ class SSL_Box { * 设置虚拟主机名 * @param host 虚拟主机名 * @return 是否成功 + * Sets the virtual host name + * @param host Virtual host name + * @return Whether the operation was successful + + * [AUTO-TRANSLATED:eebc1e2f] */ bool setHost(const char *host); diff --git a/src/Util/SSLUtil.cpp b/src/Util/SSLUtil.cpp index 72074131e..65677cd2d 100644 --- a/src/Util/SSLUtil.cpp +++ b/src/Util/SSLUtil.cpp @@ -44,12 +44,14 @@ std::string SSLUtil::getLastError() { #if defined(ENABLE_OPENSSL) static int getCerType(BIO *bio, const char *passwd, X509 **x509, int type) { - //尝试pem格式 + //尝试pem格式 [AUTO-TRANSLATED:8debedc8] + //Try pem format if (type == 1 || type == 0) { if (type == 0) { BIO_reset(bio); } - // 尝试PEM格式 + // 尝试PEM格式 [AUTO-TRANSLATED:311e0a11] + //Try PEM format *x509 = PEM_read_bio_X509(bio, nullptr, nullptr, nullptr); if (*x509) { return 1; @@ -60,7 +62,8 @@ static int getCerType(BIO *bio, const char *passwd, X509 **x509, int type) { if (type == 0) { BIO_reset(bio); } - //尝试DER格式 + //尝试DER格式 [AUTO-TRANSLATED:97ea1386] + //Try DER format *x509 = d2i_X509_bio(bio, nullptr); if (*x509) { return 2; @@ -71,7 +74,8 @@ static int getCerType(BIO *bio, const char *passwd, X509 **x509, int type) { if (type == 0) { BIO_reset(bio); } - //尝试p12格式 + //尝试p12格式 [AUTO-TRANSLATED:32331d1d] + //Try p12 format PKCS12 *p12 = d2i_PKCS12_bio(bio, nullptr); if (p12) { EVP_PKEY *pkey = nullptr; @@ -140,10 +144,12 @@ shared_ptr SSLUtil::loadPrivateKey(const string &file_path_or_data, co BIO_free(bio); }); - //尝试pem格式 + //尝试pem格式 [AUTO-TRANSLATED:8debedc8] + //Try pem format EVP_PKEY *evp_key = PEM_read_bio_PrivateKey(bio, nullptr, cb, (void *) &passwd); if (!evp_key) { - //尝试p12格式 + //尝试p12格式 [AUTO-TRANSLATED:32331d1d] + //Try p12 format BIO_reset(bio); PKCS12 *p12 = d2i_PKCS12_bio(bio, nullptr); if (!p12) { @@ -177,18 +183,22 @@ shared_ptr SSLUtil::makeSSLContext(const vector > &cer } int i = 0; for (auto &cer : cers) { - //加载公钥 + //加载公钥 [AUTO-TRANSLATED:d3cadbdf] + //Load public key if (i++ == 0) { - //SSL_CTX_use_certificate内部会调用X509_up_ref,所以这里不用X509_dup + //SSL_CTX_use_certificate内部会调用X509_up_ref,所以这里不用X509_dup [AUTO-TRANSLATED:610aca57] + //SSL_CTX_use_certificate internally calls X509_up_ref, so no need to use X509_dup here SSL_CTX_use_certificate(ctx, cer.get()); } else { - //需要先拷贝X509对象,否则指针会失效 + //需要先拷贝X509对象,否则指针会失效 [AUTO-TRANSLATED:c6cb5ebf] + //Need to copy X509 object first, otherwise the pointer will be invalid SSL_CTX_add_extra_chain_cert(ctx, X509_dup(cer.get())); } } if (key) { - //提供了私钥 + //提供了私钥 [AUTO-TRANSLATED:1b23bc8c] + //Provided private key if (SSL_CTX_use_PrivateKey(ctx, key.get()) != 1) { WarnL << "SSL_CTX_use_PrivateKey failed: " << getLastError(); SSL_CTX_free(ctx); @@ -197,7 +207,8 @@ shared_ptr SSLUtil::makeSSLContext(const vector > &cer } if (key || checkKey) { - //加载私钥成功 + //加载私钥成功 [AUTO-TRANSLATED:80e96abb] + //Private key loaded successfully if (SSL_CTX_check_private_key(ctx) != 1) { WarnL << "SSL_CTX_check_private_key failed: " << getLastError(); SSL_CTX_free(ctx); @@ -205,7 +216,8 @@ shared_ptr SSLUtil::makeSSLContext(const vector > &cer } } - //公钥私钥匹配或者没有公私钥 + //公钥私钥匹配或者没有公私钥 [AUTO-TRANSLATED:b12ac3e6] + //Public and private key match or no public and private key return shared_ptr(ctx, [](SSL_CTX *ptr) { SSL_CTX_free(ptr); }); #else return nullptr; @@ -373,7 +385,8 @@ string SSLUtil::getServerName(X509 *cer) { if (!cer) { return ""; } - //获取证书里的域名 + //获取证书里的域名 [AUTO-TRANSLATED:97830946] + //Get domain name from certificate X509_NAME *name = X509_get_subject_name(cer); char ret[256] = {0}; X509_NAME_get_text_by_NID(name, NID_commonName, ret, sizeof(ret)); diff --git a/src/Util/SSLUtil.h b/src/Util/SSLUtil.h index 4c8820ba7..b84556670 100644 --- a/src/Util/SSLUtil.h +++ b/src/Util/SSLUtil.h @@ -27,6 +27,12 @@ namespace toolkit { * pem:这个是base64的字符编码串,可能存在公钥、私钥或者两者都存在 * cer:只且只能是公钥,可以与pem的私钥配合使用 * p12:必须包括私钥和公钥 + * SSL certificate suffixes are generally divided into the following types + * pem: This is a base64 character encoded string, which may contain a public key, private key, or both + * cer: Only and must be a public key, can be used with pem private key + * p12: Must include both private key and public key + + * [AUTO-TRANSLATED:1cae2cfa] */ class SSLUtil { public: @@ -38,6 +44,14 @@ class SSLUtil { * @param file_path_or_data 文件路径或文件内容 * @param isFile 是否为文件 * @return 公钥证书列表 + * Load public key certificate, support pem, p12, cer suffixes + * When openssl loads p12 certificate, it will verify whether the public key and private key match, + * so when loading p12 public key, you may need to pass in the certificate password + * @param file_path_or_data File path or file content + * @param isFile Whether it is a file + * @return Public key certificate list + + * [AUTO-TRANSLATED:d9dbac61] */ static std::vector > loadPublicKey(const std::string &file_path_or_data, const std::string &passwd = "", bool isFile = true); @@ -47,6 +61,13 @@ class SSLUtil { * @param passwd 密码 * @param isFile 是否为文件 * @return 私钥证书 + * Load private key certificate, support pem, p12 suffixes + * @param file_path_or_data File path or file content + * @param passwd Password + * @param isFile Whether it is a file + * @return Private key certificate + + * [AUTO-TRANSLATED:73c495c8] */ static std::shared_ptr loadPrivateKey(const std::string &file_path_or_data, const std::string &passwd = "", bool isFile = true); @@ -56,12 +77,23 @@ class SSLUtil { * @param key 私钥 * @param serverMode 是否为服务器模式或客户端模式 * @return SSL_CTX对象 + * Create SSL_CTX object + * @param cer Public key array + * @param key Private key + * @param serverMode Whether it is server mode or client mode + * @return SSL_CTX object + + * [AUTO-TRANSLATED:d0faa6a4] */ static std::shared_ptr makeSSLContext(const std::vector > &cers, const std::shared_ptr &key, bool serverMode = true, bool checkKey = false); /** * 创建ssl对象 * @param ctx SSL_CTX对象 + * Create ssl object + * @param ctx SSL_CTX object + + * [AUTO-TRANSLATED:2e3eb193] */ static std::shared_ptr makeSSL(SSL_CTX *ctx); @@ -74,11 +106,24 @@ class SSLUtil { * Alternatively the SSL_CERT_FILE environment variable can be defined to override this location. * 信任/usr/local/ssl/certs/目录下的所有证书/usr/local/ssl/cert.pem的证书 * 环境变量SSL_CERT_FILE将替换/usr/local/ssl/cert.pem的路径 + * specifies that the default locations from which CA certificates are loaded should be used. + * There is one default directory and one default file. + * The default CA certificates directory is called "certs" in the default OpenSSL directory. + * Alternatively the SSL_CERT_DIR environment variable can be defined to override this location. + * The default CA certificates file is called "cert.pem" in the default OpenSSL directory. + * Alternatively the SSL_CERT_FILE environment variable can be defined to override this location. + * Trust all certificates in the /usr/local/ssl/certs/ directory and /usr/local/ssl/cert.pem + * The environment variable SSL_CERT_FILE will replace the path of /usr/local/ssl/cert.pem + + * [AUTO-TRANSLATED:f13fc4c5] */ static bool loadDefaultCAs(SSL_CTX *ctx); /** * 信任某公钥 + * Trust a public key + + * [AUTO-TRANSLATED:08987c7e] */ static bool trustCertificate(SSL_CTX *ctx, X509 *cer); @@ -88,6 +133,12 @@ class SSLUtil { * @param cer 待验证的证书 * @param ... 信任的CA根证书,X509类型,以nullptr结尾 * @return 是否合法 + * Verify the validity of the certificate + * @param cer Certificate to be verified + * @param ... Trusted CA root certificates, X509 type, ending with nullptr + * @return Whether it is valid + + * [AUTO-TRANSLATED:1b026a8f] */ static bool verifyX509(X509 *cer, ...); @@ -97,6 +148,14 @@ class SSLUtil { * @param in_str 加密或解密的原始数据,实测加密最大支持245个字节,加密后数据长度固定为256个字节 * @param enc_or_dec true:加密,false:解密 * @return 加密或解密后的数据 + * Use public key to encrypt and decrypt data + * @param cer Public key, must be ras public key + * @param in_str Original data to be encrypted or decrypted, tested to support up to 245 bytes, + * encrypted data length is fixed at 256 bytes + * @param enc_or_dec true: Encrypt, false: Decrypt + * @return Encrypted or decrypted data + + * [AUTO-TRANSLATED:77bc2939] */ static std::string cryptWithRsaPublicKey(X509 *cer, const std::string &in_str, bool enc_or_dec); @@ -106,6 +165,14 @@ class SSLUtil { * @param in_str 加密或解密的原始数据,实测加密最大支持245个字节,加密后数据长度固定为256个字节 * @param enc_or_dec true:加密,false:解密 * @return 加密或解密后的数据 + * Use private key to encrypt and decrypt data + * @param private_key Private key, must be ras private key + * @param in_str Original data to be encrypted or decrypted, tested to support up to 245 bytes, + * encrypted data length is fixed at 256 bytes + * @param enc_or_dec true: Encrypt, false: Decrypt + * @return Encrypted or decrypted data + + * [AUTO-TRANSLATED:a6e4aeb0] */ static std::string cryptWithRsaPrivateKey(EVP_PKEY *private_key, const std::string &in_str, bool enc_or_dec); @@ -113,6 +180,11 @@ class SSLUtil { * 获取证书域名 * @param cer 证书公钥 * @return 证书域名 + * Get certificate domain name + * @param cer Certificate public key + * @return Certificate domain name + + * [AUTO-TRANSLATED:b3806b53] */ static std::string getServerName(X509 *cer); }; diff --git a/src/Util/SpeedStatistic.h b/src/Util/SpeedStatistic.h index 16b1aad83..e151c8bda 100644 --- a/src/Util/SpeedStatistic.h +++ b/src/Util/SpeedStatistic.h @@ -22,11 +22,15 @@ class BytesSpeed { /** * 添加统计字节 + * Add statistical bytes + + * [AUTO-TRANSLATED:d6697ac9] */ BytesSpeed &operator+=(size_t bytes) { _bytes += bytes; if (_bytes > 1024 * 1024) { - //数据大于1MB就计算一次网速 + //数据大于1MB就计算一次网速 [AUTO-TRANSLATED:897af4d6] + //Data greater than 1MB is calculated once for network speed computeSpeed(); } return *this; @@ -34,10 +38,14 @@ class BytesSpeed { /** * 获取速度,单位bytes/s + * Get speed, unit bytes/s + + * [AUTO-TRANSLATED:41e26e29] */ int getSpeed() { if (_ticker.elapsedTime() < 1000) { - //获取频率小于1秒,那么返回上次计算结果 + //获取频率小于1秒,那么返回上次计算结果 [AUTO-TRANSLATED:b687b762] + //Get frequency less than 1 second, return the last calculation result return _speed; } return computeSpeed(); diff --git a/src/Util/SqlConnection.h b/src/Util/SqlConnection.h index 33a9f5015..34b28ae20 100644 --- a/src/Util/SqlConnection.h +++ b/src/Util/SqlConnection.h @@ -33,6 +33,9 @@ namespace toolkit { /** * 数据库异常类 + * Database exception class + + * [AUTO-TRANSLATED:f92df85e] */ class SqlException : public std::exception { public: @@ -56,6 +59,9 @@ class SqlException : public std::exception { /** * mysql连接 + * MySQL connection + + * [AUTO-TRANSLATED:a2deb48d] */ class SqlConnection { public: @@ -67,6 +73,15 @@ class SqlConnection { * @param username 用户名 * @param password 用户密码 * @param character 字符集 + * Constructor + * @param url Database address + * @param port Database port number + * @param dbname Database name + * @param username Username + * @param password User password + * @param character Character set + + * [AUTO-TRANSLATED:410a33a6] */ SqlConnection(const std::string &url, unsigned short port, const std::string &dbname, const std::string &username, @@ -79,7 +94,8 @@ class SqlConnection { mysql_close(&_sql); throw SqlException("mysql_real_connect", mysql_error(&_sql)); } - //兼容bool与my_bool + //兼容bool与my_bool [AUTO-TRANSLATED:7d8d4190] + //Compatible with bool and my_bool uint32_t reconnect = 0x01010101; mysql_options(&_sql, MYSQL_OPT_RECONNECT, &reconnect); mysql_set_character_set(&_sql, character.data()); @@ -95,6 +111,13 @@ class SqlConnection { * @param fmt printf类型fmt * @param arg 可变参数列表 * @return 影响行数 + * Execute SQL in printf style, no data returned + * @param rowId Insert rowid when inserting + * @param fmt printf type fmt + * @param arg Variable argument list + * @return Affected rows + + * [AUTO-TRANSLATED:7c72ab80] */ template int64_t query(int64_t &rowId, Fmt &&fmt, Args &&...arg) { @@ -114,6 +137,14 @@ class SqlConnection { * @param fmt printf类型fmt * @param arg 可变参数列表 * @return 影响行数 + * Execute SQL in printf style, and return list type result (excluding column names) + * @param rowId Insert rowid when inserting + * @param ret Returned data list + * @param fmt printf type fmt + * @param arg Variable argument list + * @return Affected rows + + * [AUTO-TRANSLATED:57baa44e] */ template int64_t query(int64_t &rowId, std::vector > &ret, Fmt &&fmt, Args &&...arg) { @@ -137,6 +168,14 @@ class SqlConnection { * @param fmt printf类型fmt * @param arg 可变参数列表 * @return 影响行数 + * Execute SQL in printf style, and return Map type result (including column names) + * @param rowId Insert rowid when inserting + * @param ret Returned data list + * @param fmt printf type fmt + * @param arg Variable argument list + * @return Affected rows + + * [AUTO-TRANSLATED:a12a695e] */ template int64_t query(int64_t &rowId, std::vector &ret, Fmt &&fmt, Args &&...arg) { diff --git a/src/Util/SqlPool.h b/src/Util/SqlPool.h index 9e6514e83..0c3015c32 100644 --- a/src/Util/SqlPool.h +++ b/src/Util/SqlPool.h @@ -43,6 +43,10 @@ class SqlPool : public std::enable_shared_from_this { /** * 设置循环池对象个数 * @param size + * Sets the number of loop pool objects + * @param size + + * [AUTO-TRANSLATED:a3f3a8ac] */ void setSize(int size) { checkInited(); @@ -53,6 +57,11 @@ class SqlPool : public std::enable_shared_from_this { * 初始化循环池,设置数据库连接参数 * @tparam Args * @param arg + * Initializes the loop pool and sets the database connection parameters + * @tparam Args + * @param arg + + * [AUTO-TRANSLATED:fff84748] */ template void Init(Args &&...arg) { @@ -65,6 +74,11 @@ class SqlPool : public std::enable_shared_from_this { * 异步执行sql * @param str sql语句 * @param tryCnt 重试次数 + * Asynchronously executes SQL + * @param str SQL statement + * @param tryCnt Number of retries + + * [AUTO-TRANSLATED:9d2414e1] */ template void asyncQuery(Args &&...args) { @@ -77,6 +91,12 @@ class SqlPool : public std::enable_shared_from_this { * @tparam Args 可变参数类型列表 * @param arg 可变参数列表 * @return 影响行数 + * Synchronously executes SQL + * @tparam Args Variable parameter type list + * @param arg Variable parameter list + * @return Number of affected rows + + * [AUTO-TRANSLATED:ba47cb3c] */ template @@ -84,7 +104,8 @@ class SqlPool : public std::enable_shared_from_this { checkInited(); typename PoolType::ValuePtr mysql; try { - //捕获执行异常 + //捕获执行异常 [AUTO-TRANSLATED:ae8a1093] + //Capture execution exceptions mysql = _pool->obtain(); return mysql->query(std::forward(arg)...); } catch (std::exception &e) { @@ -98,6 +119,11 @@ class SqlPool : public std::enable_shared_from_this { * sql转义 * @param str * @return + * Escapes SQL + * @param str + * @return + + * [AUTO-TRANSLATED:e7a99a20] */ std::string escape(const std::string &str) { checkInited(); @@ -117,6 +143,11 @@ class SqlPool : public std::enable_shared_from_this { * 异步执行sql * @param sql sql语句 * @param tryCnt 重试次数 + * Asynchronously executes SQL + * @param sql SQL statement + * @param tryCnt Number of retries + + * [AUTO-TRANSLATED:6f585bf1] */ void asyncQuery_l(const std::string &sql, int tryCnt = 3) { auto lam = [this, sql, tryCnt]() { @@ -126,7 +157,8 @@ class SqlPool : public std::enable_shared_from_this { syncQuery(rowID, sql); } catch (std::exception &ex) { if (cnt > 0) { - //失败重试 + //失败重试 [AUTO-TRANSLATED:ef091479] + //Retry on failure std::lock_guard lk(_error_query_mutex); sqlQuery query(sql, cnt); _error_query.push_back(query); @@ -140,6 +172,9 @@ class SqlPool : public std::enable_shared_from_this { /** * 定时重试失败的sql + * Periodically retries failed SQL + + * [AUTO-TRANSLATED:33048898] */ void flushError() { decltype(_error_query) query_copy; @@ -154,6 +189,9 @@ class SqlPool : public std::enable_shared_from_this { /** * 检查数据库连接池是否初始化 + * Checks if the database connection pool is initialized + + * [AUTO-TRANSLATED:176fceed] */ void checkInited() { if (!_pool) { @@ -179,6 +217,9 @@ class SqlPool : public std::enable_shared_from_this { /** * Sql语句生成器,通过占位符'?'的方式生成sql语句 + * SQL statement generator, generates SQL statements through the '?' placeholder + + * [AUTO-TRANSLATED:12f34981] */ class SqlStream { public: @@ -217,6 +258,9 @@ class SqlStream { /** * sql查询器 + * SQL query executor + + * [AUTO-TRANSLATED:50396624] */ class SqlWriter { public: @@ -224,6 +268,11 @@ class SqlWriter { * 构造函数 * @param sql 带'?'占位符的sql模板 * @param throwAble 是否抛异常 + * Constructor + * @param sql SQL template with '?' placeholder + * @param throwAble Whether to throw exceptions + + * [AUTO-TRANSLATED:97c6d354] */ SqlWriter(const char *sql, bool throwAble = true) : _sqlstream(sql), _throwAble(throwAble) {} @@ -234,13 +283,20 @@ class SqlWriter { * @tparam T 参数类型 * @param data 参数 * @return 本身引用 + * Replaces '?' placeholders with input parameters to generate SQL statements; may throw exceptions + * @tparam T Parameter type + * @param data Parameter + * @return Self-reference + + * [AUTO-TRANSLATED:9bdc6917] */ template SqlWriter &operator<<(T &&data) { try { _sqlstream << std::forward(data); } catch (std::exception &ex) { - //在转义sql时可能抛异常 + //在转义sql时可能抛异常 [AUTO-TRANSLATED:ce6314cc] + //May throw exceptions when escaping SQL if (!_throwAble) { WarnL << "Commit sql failed: " << ex.what(); } else { @@ -253,9 +309,14 @@ class SqlWriter { /** * 异步执行sql,不会抛异常 * @param f std::endl + * Asynchronously executes SQL, does not throw exceptions + * @param f std::endl + + * [AUTO-TRANSLATED:e203d266] */ void operator<<(std::ostream &(*f)(std::ostream &)) { - //异步执行sql不会抛异常 + //异步执行sql不会抛异常 [AUTO-TRANSLATED:4370797e] + //Asynchronously executes SQL, does not throw exceptions SqlPool::Instance().asyncQuery((std::string) _sqlstream); } @@ -265,6 +326,13 @@ class SqlWriter { * 也可以是map/Json::Value 等支持 obj["key"] = "value"操作的数据类型 * @param ret 数据存放对象 * @return 影响行数 + * Synchronously executes SQL, may throw exceptions + * @tparam Row Data row type, can be vector/list or other types that support obj.emplace_back("value") operations + * Can also be map/Json::Value or other types that support obj["key"] = "value" operations + * @param ret Data storage object + * @return Number of affected rows + + * [AUTO-TRANSLATED:d8e40f96] */ template int64_t operator<<(std::vector &ret) { @@ -283,6 +351,10 @@ class SqlWriter { /** * 在insert数据库时返回插入的rowid * @return + * Returns the rowid inserted into the database when inserting data + * @return + + * [AUTO-TRANSLATED:699edcc4] */ int64_t getRowID() const { return _rowId; @@ -291,6 +363,10 @@ class SqlWriter { /** * 返回影响数据库数据行数 * @return + * Returns the number of rows affected in the database + * @return + + * [AUTO-TRANSLATED:81af02d9] */ int64_t getAffectedRows() const { return _affectedRows; diff --git a/src/Util/TimeTicker.h b/src/Util/TimeTicker.h index 9b31d509e..f6dac4d00 100644 --- a/src/Util/TimeTicker.h +++ b/src/Util/TimeTicker.h @@ -23,6 +23,12 @@ class Ticker { * @param min_ms 开启码执行时间统计时,如果代码执行耗时超过该参数,则打印警告日志 * @param ctx 日志上下文捕获,用于捕获当前日志代码所在位置 * @param print_log 是否打印代码执行时间 + * This object can be used for code execution time statistics, and can be used for general timing + * @param min_ms When the code execution time statistics is enabled, if the code execution time exceeds this parameter, a warning log is printed + * @param ctx Log context capture, used to capture the current log code location + * @param print_log Whether to print the code execution time + + * [AUTO-TRANSLATED:4436cf19] */ Ticker(uint64_t min_ms = 0, LogContextCapture ctx = LogContextCapture(Logger::Instance(), LWarn, __FILE__, "", __LINE__), @@ -45,6 +51,9 @@ class Ticker { /** * 获取上次resetTime后至今的时间,单位毫秒 + * Get the time from the last resetTime to now, in milliseconds + + * [AUTO-TRANSLATED:739ad90a] */ uint64_t elapsedTime() const { return getCurrentMillisecond() - _begin; @@ -52,6 +61,9 @@ class Ticker { /** * 获取从创建至今的时间,单位毫秒 + * Get the time from creation to now, in milliseconds + + * [AUTO-TRANSLATED:83a189e2] */ uint64_t createdTime() const { return getCurrentMillisecond() - _created; @@ -59,6 +71,9 @@ class Ticker { /** * 重置计时器 + * Reset the timer + + * [AUTO-TRANSLATED:2500c6f1] */ void resetTime() { _begin = getCurrentMillisecond(); @@ -76,6 +91,10 @@ class SmoothTicker { /** * 此对象用于生成平滑的时间戳 * @param reset_ms 时间戳重置间隔,没间隔reset_ms毫秒, 生成的时间戳会同步一次系统时间戳 + * This object is used to generate smooth timestamps + * @param reset_ms Timestamp reset interval, every reset_ms milliseconds, the generated timestamp will be synchronized with the system timestamp + + * [AUTO-TRANSLATED:0ff567e7] */ SmoothTicker(uint64_t reset_ms = 10000) { _reset_ms = reset_ms; @@ -86,6 +105,9 @@ class SmoothTicker { /** * 返回平滑的时间戳,防止由于网络抖动导致时间戳不平滑 + * Return a smooth timestamp, to prevent the timestamp from being unsmooth due to network jitter + + * [AUTO-TRANSLATED:26f78ae3] */ uint64_t elapsedTime() { auto now_time = _ticker.elapsedTime(); @@ -117,6 +139,9 @@ class SmoothTicker { /** * 时间戳重置为0开始 + * Reset the timestamp to start from 0 + + * [AUTO-TRANSLATED:ca42c3d1] */ void resetTime() { _first_time = 0; diff --git a/src/Util/base64.h b/src/Util/base64.h index e762614ec..7bf18a9dd 100644 --- a/src/Util/base64.h +++ b/src/Util/base64.h @@ -58,6 +58,11 @@ char *av_base64_encode(char *out, int out_size, const uint8_t *in, int in_size); * 编码base64 * @param txt 明文 * @return 密文 + * Encode base64 + * @param txt plaintext + * @return ciphertext + + * [AUTO-TRANSLATED:72045f2c] */ std::string encodeBase64(const std::string &txt); @@ -65,6 +70,11 @@ std::string encodeBase64(const std::string &txt); * 解码base64 * @param txt 密文 * @return 明文 + * Decode base64 + * @param txt ciphertext + * @return plaintext + + * [AUTO-TRANSLATED:115e667b] */ std::string decodeBase64(const std::string &txt); diff --git a/src/Util/function_traits.h b/src/Util/function_traits.h index 14ad03010..ab3c95050 100644 --- a/src/Util/function_traits.h +++ b/src/Util/function_traits.h @@ -9,7 +9,8 @@ namespace toolkit { template struct function_traits; -//普通函数 +//普通函数 [AUTO-TRANSLATED:569a9de3] +//Ordinary function template struct function_traits { @@ -28,7 +29,8 @@ struct function_traits }; }; -//函数指针 +//函数指针 [AUTO-TRANSLATED:bc15033e] +//Function pointer template struct function_traits : function_traits{}; @@ -46,7 +48,8 @@ FUNCTION_TRAITS(const) FUNCTION_TRAITS(volatile) FUNCTION_TRAITS(const volatile) -//函数对象 +//函数对象 [AUTO-TRANSLATED:a0091563] +//Function object template struct function_traits : function_traits{}; diff --git a/src/Util/logger.h b/src/Util/logger.h index b88673554..96217cbd6 100644 --- a/src/Util/logger.h +++ b/src/Util/logger.h @@ -40,6 +40,9 @@ void setLogger(Logger *logger); /** * 日志类 + * Log class + + * [AUTO-TRANSLATED:3f74af09] */ class Logger : public std::enable_shared_from_this, public noncopyable { public: @@ -49,6 +52,10 @@ class Logger : public std::enable_shared_from_this, public noncopyable { /** * 获取日志单例 * @return + * Get log singleton + * @return + + * [AUTO-TRANSLATED:9f0d1ed7] */ static Logger &Instance(); @@ -58,12 +65,20 @@ class Logger : public std::enable_shared_from_this, public noncopyable { /** * 添加日志通道,非线程安全的 * @param channel log通道 + * Add log channel, not thread-safe + * @param channel log channel + + * [AUTO-TRANSLATED:4c801098] */ void add(const std::shared_ptr &channel); /** * 删除日志通道,非线程安全的 * @param name log通道名 + * Delete log channel, not thread-safe + * @param name log channel name + + * [AUTO-TRANSLATED:fa78e18b] */ void del(const std::string &name); @@ -71,30 +86,51 @@ class Logger : public std::enable_shared_from_this, public noncopyable { * 获取日志通道,非线程安全的 * @param name log通道名 * @return 线程通道 + * Get log channel, not thread-safe + * @param name log channel name + * @return log channel + + * [AUTO-TRANSLATED:4fa3f6c3] */ std::shared_ptr get(const std::string &name); /** * 设置写log器,非线程安全的 * @param writer 写log器 + * Set log writer, not thread-safe + * @param writer log writer + + * [AUTO-TRANSLATED:da1403f7] */ void setWriter(const std::shared_ptr &writer); /** * 设置所有日志通道的log等级 * @param level log等级 + * Set log level for all log channels + * @param level log level + + * [AUTO-TRANSLATED:d064460c] */ void setLevel(LogLevel level); /** * 获取logger名 * @return logger名 + * Get logger name + * @return logger name + + * [AUTO-TRANSLATED:e0de492b] */ const std::string &getName() const; /** * 写日志 * @param ctx 日志信息 + * Write log + * @param ctx log information + + * [AUTO-TRANSLATED:4f29cde6] */ void write(const LogContextPtr &ctx); @@ -102,6 +138,10 @@ class Logger : public std::enable_shared_from_this, public noncopyable { /** * 写日志到各channel,仅供AsyncLogWriter调用 * @param ctx 日志信息 + * Write log to each channel, only for AsyncLogWriter to call + * @param ctx log information + + * [AUTO-TRANSLATED:caad57f4] */ void writeChannels(const LogContextPtr &ctx); void writeChannels_l(const LogContextPtr &ctx); @@ -117,11 +157,16 @@ class Logger : public std::enable_shared_from_this, public noncopyable { ///////////////////LogContext/////////////////// /** * 日志上下文 + * Log Context + + * [AUTO-TRANSLATED:f2805fe8] */ class LogContext : public std::ostringstream { public: - //_file,_function改成string保存,目的是有些情况下,指针可能会失效 - //比如说动态库中打印了一条日志,然后动态库卸载了,那么指向静态数据区的指针就会失效 + //_file,_function改成string保存,目的是有些情况下,指针可能会失效 [AUTO-TRANSLATED:8e4b3f48] + //_file,_function changed to string to save, the purpose is that in some cases, the pointer may become invalid + //比如说动态库中打印了一条日志,然后动态库卸载了,那么指向静态数据区的指针就会失效 [AUTO-TRANSLATED:d5e087bc] + //For example, a log is printed in a dynamic library, and then the dynamic library is unloaded, so the pointer to the static data area will become invalid LogContext() = default; LogContext(LogLevel level, const char *file, const char *function, int line, const char *module_name, const char *flag); ~LogContext() = default; @@ -145,6 +190,9 @@ class LogContext : public std::ostringstream { /** * 日志上下文捕获器 + * Log Context Capturer + + * [AUTO-TRANSLATED:3c5ddc22] */ class LogContextCapture { public: @@ -158,6 +206,11 @@ class LogContextCapture { * 输入std::endl(回车符)立即输出日志 * @param f std::endl(回车符) * @return 自身引用 + * Input std::endl (newline character) to output log immediately + * @param f std::endl (newline character) + * @return Self-reference + + * [AUTO-TRANSLATED:019b9eea] */ LogContextCapture &operator<<(std::ostream &(*f)(std::ostream &)); @@ -181,6 +234,9 @@ class LogContextCapture { ///////////////////LogWriter/////////////////// /** * 写日志器 + * Log Writer + + * [AUTO-TRANSLATED:f70397d4] */ class LogWriter : public noncopyable { public: @@ -211,6 +267,9 @@ class AsyncLogWriter : public LogWriter { ///////////////////LogChannel/////////////////// /** * 日志通道 + * Log Channel + + * [AUTO-TRANSLATED:afbe7d5f] */ class LogChannel : public noncopyable { public: @@ -228,6 +287,12 @@ class LogChannel : public noncopyable { * @param ost 输出流 * @param enable_color 是否启用颜色 * @param enable_detail 是否打印细节(函数名、源码文件名、源码行) + * Print log to output stream + * @param ost Output stream + * @param enable_color Whether to enable color + * @param enable_detail Whether to print details (function name, source file name, source line) + + * [AUTO-TRANSLATED:54c78737] */ virtual void format(const Logger &logger, std::ostream &ost, const LogContextPtr &ctx, bool enable_color = true, bool enable_detail = true); @@ -238,14 +303,20 @@ class LogChannel : public noncopyable { /** * 输出日至到广播 + * Output log to broadcast + + * [AUTO-TRANSLATED:ee99643f] */ class EventChannel : public LogChannel { public: - //输出日志时的广播名 + //输出日志时的广播名 [AUTO-TRANSLATED:2214541b] + //Broadcast name when outputting log static const std::string kBroadcastLogEvent; - //toolkit目前仅只有一处全局变量被外部引用,减少导出相关定义,导出以下函数避免导出kBroadcastLogEvent + //toolkit目前仅只有一处全局变量被外部引用,减少导出相关定义,导出以下函数避免导出kBroadcastLogEvent [AUTO-TRANSLATED:71271efd] + //The toolkit currently only has one global variable referenced externally, reducing the export of related definitions, and exporting the following functions to avoid exporting kBroadcastLogEvent static const std::string& getBroadcastLogEventName(); - //日志广播参数类型和列表 + //日志广播参数类型和列表 [AUTO-TRANSLATED:20255585] + //Log broadcast parameter type and list #define BroadcastLogEventArgs const Logger &logger, const LogContextPtr &ctx EventChannel(const std::string &name = "EventChannel", LogLevel level = LTrace); @@ -256,6 +327,9 @@ class EventChannel : public LogChannel { /** * 输出日志至终端,支持输出日志至android logcat + * Output logs to the terminal, supporting output to Android logcat + + * [AUTO-TRANSLATED:538b78dc] */ class ConsoleChannel : public LogChannel { public: @@ -267,6 +341,9 @@ class ConsoleChannel : public LogChannel { /** * 输出日志至文件 + * Output logs to a file + + * [AUTO-TRANSLATED:c905542e] */ class FileChannelBase : public LogChannel { public: @@ -292,6 +369,10 @@ class Ticker; /** * 自动清理的日志文件通道 * 默认最多保存30天的日志 + * Auto-cleaning log file channel + * Default to keep logs for up to 30 days + + * [AUTO-TRANSLATED:700cb04b] */ class FileChannel : public FileChannelBase { public: @@ -302,52 +383,82 @@ class FileChannel : public FileChannelBase { * 写日志时才会触发新建日志文件或者删除老的日志文件 * @param logger * @param stream + * Trigger new log file creation or deletion of old log files when writing logs + * @param logger + * @param stream + + * [AUTO-TRANSLATED:b8e3a717] */ void write(const Logger &logger, const LogContextPtr &ctx) override; /** * 设置日志最大保存天数 * @param max_day 天数 + * Set the maximum number of days to keep logs + * @param max_day Number of days + + * [AUTO-TRANSLATED:317426b9] */ void setMaxDay(size_t max_day); /** * 设置日志切片文件最大大小 * @param max_size 单位MB + * Set the maximum size of log slice files + * @param max_size Unit: MB + + * [AUTO-TRANSLATED:071a8ec2] */ void setFileMaxSize(size_t max_size); /** * 设置日志切片文件最大个数 * @param max_count 个数 + * Set the maximum number of log slice files + * @param max_count Number of files + + * [AUTO-TRANSLATED:74da4e7f] */ void setFileMaxCount(size_t max_count); private: /** * 删除日志切片文件,条件为超过最大保存天数与最大切片个数 + * Delete log slice files, conditions are exceeding the maximum number of days and slices + + * [AUTO-TRANSLATED:9ddfccec] */ void clean(); /** * 检查当前日志切片文件大小,如果超过限制,则创建新的日志切片文件 + * Check the current log slice file size, if exceeded the limit, create a new log slice file + + * [AUTO-TRANSLATED:cfb08734] */ void checkSize(time_t second); /** * 创建并切换到下一个日志切片文件 + * Create and switch to the next log slice file + + * [AUTO-TRANSLATED:dc55a521] */ void changeFile(time_t second); private: bool _can_write = false; - //默认最多保存30天的日志文件 + //默认最多保存30天的日志文件 [AUTO-TRANSLATED:f16d4661] + //Default to keep log files for up to 30 days size_t _log_max_day = 30; - //每个日志切片文件最大默认128MB + //每个日志切片文件最大默认128MB [AUTO-TRANSLATED:6d3efa5e] + //Maximum default size of each log slice file is 128MB size_t _log_max_size = 128; - //最多默认保持30个日志切片文件 + //最多默认保持30个日志切片文件 [AUTO-TRANSLATED:90689f74] + //Default to keep up to 30 log slice files size_t _log_max_count = 30; - //当前日志切片文件索引 + //当前日志切片文件索引 [AUTO-TRANSLATED:a9894a48] + //Current log slice file index size_t _index = 0; int64_t _last_day = -1; time_t _last_check_time = 0; @@ -369,7 +480,8 @@ class SysLogChannel : public LogChannel { class BaseLogFlagInterface { protected: virtual ~BaseLogFlagInterface() {} - // 获得日志标记Flag + // 获得日志标记Flag [AUTO-TRANSLATED:a8326285] + //Get log flag const char* getLogFlag(){ return _log_flag; } @@ -400,15 +512,18 @@ class LoggerWrapper { template static inline void appendLog(Log &out) {} - //printf样式的日志打印 + //printf样式的日志打印 [AUTO-TRANSLATED:4a52190b] + //printf style log print static void printLog(Logger &logger, int level, const char *file, const char *function, int line, const char *fmt, ...); static void printLogV(Logger &logger, int level, const char *file, const char *function, int line, const char *fmt, va_list ap); }; -//可重置默认值 +//可重置默认值 [AUTO-TRANSLATED:b1e0e8b9] +//Can reset default value extern Logger *g_defaultLogger; -//用法: DebugL << 1 << "+" << 2 << '=' << 3; +//用法: DebugL << 1 << "+" << 2 << '=' << 3; [AUTO-TRANSLATED:e6efe6cb] +//Usage: DebugL << 1 << "+" << 2 << '=' << 3; #define WriteL(level) ::toolkit::LogContextCapture(::toolkit::getLogger(), level, __FILE__, __FUNCTION__, __LINE__) #define TraceL WriteL(::toolkit::LTrace) #define DebugL WriteL(::toolkit::LDebug) @@ -416,7 +531,8 @@ extern Logger *g_defaultLogger; #define WarnL WriteL(::toolkit::LWarn) #define ErrorL WriteL(::toolkit::LError) -//只能在虚继承BaseLogFlagInterface的类中使用 +//只能在虚继承BaseLogFlagInterface的类中使用 [AUTO-TRANSLATED:a395e54d] +//Can only be used in classes that virtually inherit from BaseLogFlagInterface #define WriteF(level) ::toolkit::LogContextCapture(::toolkit::getLogger(), level, __FILE__, __FUNCTION__, __LINE__, getLogFlag()) #define TraceF WriteF(::toolkit::LTrace) #define DebugF WriteF(::toolkit::LDebug) @@ -424,7 +540,8 @@ extern Logger *g_defaultLogger; #define WarnF WriteF(::toolkit::LWarn) #define ErrorF WriteF(::toolkit::LError) -//用法: PrintD("%d + %s = %c", 1 "2", 'c'); +//用法: PrintD("%d + %s = %c", 1 "2", 'c'); [AUTO-TRANSLATED:1217cc82] +//Usage: PrintD("%d + %s = %c", 1, "2", 'c'); #define PrintLog(level, ...) ::toolkit::LoggerWrapper::printLog(::toolkit::getLogger(), level, __FILE__, __FUNCTION__, __LINE__, ##__VA_ARGS__) #define PrintT(...) PrintLog(::toolkit::LTrace, ##__VA_ARGS__) #define PrintD(...) PrintLog(::toolkit::LDebug, ##__VA_ARGS__) @@ -432,8 +549,10 @@ extern Logger *g_defaultLogger; #define PrintW(...) PrintLog(::toolkit::LWarn, ##__VA_ARGS__) #define PrintE(...) PrintLog(::toolkit::LError, ##__VA_ARGS__) -//用法: LogD(1, "+", "2", '=', 3); -//用于模板实例化的原因,如果每次打印参数个数和类型不一致,可能会导致二进制代码膨胀 +//用法: LogD(1, "+", "2", '=', 3); [AUTO-TRANSLATED:2a824fae] +//Usage: LogD(1, "+", "2", '=', 3); +//用于模板实例化的原因,如果每次打印参数个数和类型不一致,可能会导致二进制代码膨胀 [AUTO-TRANSLATED:c40b3f4e] +//Used for template instantiation, because if the number and type of print parameters are inconsistent each time, it may cause binary code bloat #define LogL(level, ...) ::toolkit::LoggerWrapper::printLogArray(::toolkit::getLogger(), (LogLevel)level, __FILE__, __FUNCTION__, __LINE__, ##__VA_ARGS__) #define LogT(...) LogL(::toolkit::LTrace, ##__VA_ARGS__) #define LogD(...) LogL(::toolkit::LDebug, ##__VA_ARGS__) diff --git a/src/Util/mini.cpp b/src/Util/mini.cpp index da94296ff..21edfeec9 100644 --- a/src/Util/mini.cpp +++ b/src/Util/mini.cpp @@ -34,7 +34,8 @@ mINI_basic &mINI_basic::Instance(){ template <> bool variant::as() const { if (empty() || isdigit(front())) { - //数字开头 + //数字开头 [AUTO-TRANSLATED:e4266329] + //Starts with a number return as_default(); } if (strToLower(std::string(*this)) == "true") { @@ -43,7 +44,8 @@ bool variant::as() const { if (strToLower(std::string(*this)) == "false") { return false; } - //未识别字符串 + //未识别字符串 [AUTO-TRANSLATED:b8037f51] + //Unrecognized string return as_default(); } diff --git a/src/Util/strptime_win.cpp b/src/Util/strptime_win.cpp index 48110dc35..834ce601d 100644 --- a/src/Util/strptime_win.cpp +++ b/src/Util/strptime_win.cpp @@ -38,8 +38,10 @@ static const char *am_pm[2] = { }; -//window上自己实现strptime函数,linux已经提供strptime -//strptime函数windows平台上实现 +//window上自己实现strptime函数,linux已经提供strptime [AUTO-TRANSLATED:0e3b2366] +//Implement strptime function on Windows, Linux already provides strptime +//strptime函数windows平台上实现 [AUTO-TRANSLATED:eb327448] +//Implement strptime function on Windows platform char * strptime(const char *buf, const char *fmt, struct tm *tm) { diff --git a/src/Util/strptime_win.h b/src/Util/strptime_win.h index 631124cc1..bd5557831 100644 --- a/src/Util/strptime_win.h +++ b/src/Util/strptime_win.h @@ -3,8 +3,10 @@ #include #ifdef _WIN32 -//window上自己实现strptime函数,linux已经提供strptime -//strptime函数windows平台上实现 +//window上自己实现strptime函数,linux已经提供strptime [AUTO-TRANSLATED:0e3b2366] +//Implement strptime function on Windows, Linux already provides strptime +//strptime函数windows平台上实现 [AUTO-TRANSLATED:eb327448] +//Implement strptime function on Windows platform char * strptime(const char *buf, const char *fmt, struct tm *tm); #endif #endif //ZLMEDIAKIT_STRPTIME_WIN_H diff --git a/src/Util/util.cpp b/src/Util/util.cpp index 43396b45a..05c0d0151 100644 --- a/src/Util/util.cpp +++ b/src/Util/util.cpp @@ -154,7 +154,8 @@ string exePath(bool isExe /*= true*/) { } #if defined(_WIN32) - //windows下把路径统一转换层unix风格,因为后续都是按照unix风格处理的 + //windows下把路径统一转换层unix风格,因为后续都是按照unix风格处理的 [AUTO-TRANSLATED:33d86ad3] + //Convert paths to Unix style under Windows, as subsequent processing is done in Unix style for (auto &ch : filePath) { if (ch == '\\') { ch = '/'; @@ -175,25 +176,29 @@ string exeName(bool isExe /*= true*/) { return path.substr(path.rfind('/') + 1); } -// string转小写 +// string转小写 [AUTO-TRANSLATED:bf92618b] +//Convert string to lowercase std::string &strToLower(std::string &str) { transform(str.begin(), str.end(), str.begin(), towlower); return str; } -// string转大写 +// string转大写 [AUTO-TRANSLATED:0197b884] +//Convert string to uppercase std::string &strToUpper(std::string &str) { transform(str.begin(), str.end(), str.begin(), towupper); return str; } -// string转小写 +// string转小写 [AUTO-TRANSLATED:bf92618b] +//Convert string to lowercase std::string strToLower(std::string &&str) { transform(str.begin(), str.end(), str.begin(), towlower); return std::move(str); } -// string转大写 +// string转大写 [AUTO-TRANSLATED:0197b884] +//Convert string to uppercase std::string strToUpper(std::string &&str) { transform(str.begin(), str.end(), str.begin(), towupper); return std::move(str); @@ -226,7 +231,8 @@ do{ \ while( s.size() && map.at((unsigned char &)s.front())) s.erase(0,1); \ }while(0); -//去除前后的空格、回车符、制表符 +//去除前后的空格、回车符、制表符 [AUTO-TRANSLATED:0b0a7fc7] +//Remove leading and trailing spaces, carriage returns, and tabs std::string &trim(std::string &s, const string &chars) { TRIM(s, chars); return s; @@ -369,22 +375,26 @@ static inline bool initMillisecondThread() { uint64_t microsecond = 0; while (true) { now = getCurrentMicrosecondOrigin(); - //记录系统时间戳,可回退 + //记录系统时间戳,可回退 [AUTO-TRANSLATED:495a0114] + //Record system timestamp, can be rolled back s_currentMicrosecond_system.store(now, memory_order_release); s_currentMillisecond_system.store(now / 1000, memory_order_release); - //记录流逝时间戳,不可回退 + //记录流逝时间戳,不可回退 [AUTO-TRANSLATED:7f3a9da3] + //Record elapsed timestamp, cannot be rolled back int64_t expired = now - last; last = now; if (expired > 0 && expired < 1000 * 1000) { - //流逝时间处于0~1000ms之间,那么是合理的,说明没有调整系统时间 + //流逝时间处于0~1000ms之间,那么是合理的,说明没有调整系统时间 [AUTO-TRANSLATED:566e1001] + //If the elapsed time is between 0~1000ms, it is reasonable, indicating that the system time has not been adjusted microsecond += expired; s_currentMicrosecond.store(microsecond, memory_order_release); s_currentMillisecond.store(microsecond / 1000, memory_order_release); } else if (expired != 0) { WarnL << "Stamp expired is abnormal: " << expired; } - //休眠0.5 ms + //休眠0.5 ms [AUTO-TRANSLATED:5e20acdd] + //Sleep for 0.5 ms usleep(500); } }); diff --git a/src/Util/util.h b/src/Util/util.h index 158d6b9b5..319fa830e 100644 --- a/src/Util/util.h +++ b/src/Util/util.h @@ -23,7 +23,8 @@ #include "function_traits.h" #if defined(_WIN32) #undef FD_SETSIZE -//修改默认64为1024路 +//修改默认64为1024路 [AUTO-TRANSLATED:90567e14] +//Modify the default 64 to 1024 paths #define FD_SETSIZE 1024 #include #pragma comment (lib,"WS2_32") @@ -72,13 +73,15 @@ class _StrPrinter : public std::string { std::stringstream _stream; }; -//禁止拷贝基类 +//禁止拷贝基类 [AUTO-TRANSLATED:a4ca4dcb] +//Prohibit copying of base classes class noncopyable { protected: noncopyable() {} ~noncopyable() {} private: - //禁止拷贝 + //禁止拷贝 [AUTO-TRANSLATED:e8af72e3] + //Prohibit copying noncopyable(const noncopyable &that) = delete; noncopyable(noncopyable &&that) = delete; noncopyable &operator=(const noncopyable &that) = delete; @@ -119,6 +122,11 @@ CLASS_FUNC_TRAITS(Create) * 对象安全的构建和析构,构建后执行onCreate函数,析构前执行onDestory函数 * 在函数onCreate和onDestory中可以执行构造或析构中不能调用的方法,比如说shared_from_this或者虚函数 * @warning onDestory函数确保参数个数为0;否则会被忽略调用 + * Object-safe construction and destruction, execute the onCreate function after construction, and execute the onDestroy function before destruction + * Methods that cannot be called during construction or destruction, such as shared_from_this or virtual functions, can be executed in the onCreate and onDestroy functions + * @warning The onDestroy function must have 0 parameters; otherwise, it will be ignored + + * [AUTO-TRANSLATED:54ef34ac] */ class Creator { public: @@ -126,6 +134,11 @@ class Creator { * 创建对象,用空参数执行onCreate和onDestory函数 * @param args 对象构造函数参数列表 * @return args对象的智能指针 + * Create an object, execute onCreate and onDestroy functions with empty parameters + * @param args List of parameters for the object's constructor + * @return Smart pointer to the args object + + * [AUTO-TRANSLATED:c6c90c2b] */ template static std::shared_ptr create(ArgsType &&...args) { @@ -146,6 +159,12 @@ class Creator { * @param args 对象onCreate函数参数列表 * @warning args参数类型和个数必须与onCreate函数类型匹配(不可忽略默认参数),否则会由于模板匹配失败导致忽略调用 * @return args对象的智能指针 + * Create an object, execute the onCreate function with specified parameters + * @param args List of parameters for the object's onCreate function + * @warning The type and number of args parameters must match the type of the onCreate function (default parameters cannot be ignored), otherwise it will be ignored due to template matching failure + * @return Smart pointer to the args object + + * [AUTO-TRANSLATED:bd672150] */ template static std::shared_ptr create2(ArgsType &&...args) { @@ -209,24 +228,32 @@ std::string exeDir(bool isExe = true); std::string exeName(bool isExe = true); std::vector split(const std::string& s, const char *delim); -//去除前后的空格、回车符、制表符... +//去除前后的空格、回车符、制表符... [AUTO-TRANSLATED:7c50cbc8] +//Remove leading and trailing spaces, line breaks, tabs... std::string& trim(std::string &s,const std::string &chars=" \r\n\t"); std::string trim(std::string &&s,const std::string &chars=" \r\n\t"); -// string转小写 +// string转小写 [AUTO-TRANSLATED:bf92618b] +//Convert string to lowercase std::string &strToLower(std::string &str); std::string strToLower(std::string &&str); -// string转大写 +// string转大写 [AUTO-TRANSLATED:0197b884] +//Convert string to uppercase std::string &strToUpper(std::string &str); std::string strToUpper(std::string &&str); -//替换子字符串 +//替换子字符串 [AUTO-TRANSLATED:cbacb116] +//Replace substring void replace(std::string &str, const std::string &old_str, const std::string &new_str, std::string::size_type b_pos = 0) ; -//判断是否为ip +//判断是否为ip [AUTO-TRANSLATED:288e7a54] +//Determine if it's an IP bool isIP(const char *str); -//字符串是否以xx开头 +//字符串是否以xx开头 [AUTO-TRANSLATED:585cf826] +//Check if a string starts with xx bool start_with(const std::string &str, const std::string &substr); -//字符串是否以xx结尾 +//字符串是否以xx结尾 [AUTO-TRANSLATED:50cc80d7] +//Check if a string ends with xx bool end_with(const std::string &str, const std::string &substr); -//拼接格式字符串 +//拼接格式字符串 [AUTO-TRANSLATED:2f902ef7] +//Concatenate format string template std::string str_format(const std::string &format, Args... args) { @@ -290,18 +317,29 @@ const char *strcasestr(const char *big, const char *little); /** * 获取时间差, 返回值单位为秒 + * Get time difference, return value in seconds + + * [AUTO-TRANSLATED:43d2403a] */ long getGMTOff(); /** * 获取1970年至今的毫秒数 * @param system_time 是否为系统时间(系统时间可以回退),否则为程序启动时间(不可回退) + * Get the number of milliseconds since 1970 + * @param system_time Whether it's system time (system time can be rolled back), otherwise it's program startup time (cannot be rolled back) + + * [AUTO-TRANSLATED:9857bfbe] */ uint64_t getCurrentMillisecond(bool system_time = false); /** * 获取1970年至今的微秒数 * @param system_time 是否为系统时间(系统时间可以回退),否则为程序启动时间(不可回退) + * Get the number of microseconds since 1970 + * @param system_time Whether it's system time (system time can be rolled back), otherwise it's program startup time (cannot be rolled back) + + * [AUTO-TRANSLATED:e4bed7e3] */ uint64_t getCurrentMicrosecond(bool system_time = false); @@ -309,6 +347,11 @@ uint64_t getCurrentMicrosecond(bool system_time = false); * 获取时间字符串 * @param fmt 时间格式,譬如%Y-%m-%d %H:%M:%S * @return 时间字符串 + * Get time string + * @param fmt Time format, e.g. %Y-%m-%d %H:%M:%S + * @return Time string + + * [AUTO-TRANSLATED:444636ec] */ std::string getTimeStr(const char *fmt,time_t time = 0); @@ -316,16 +359,27 @@ std::string getTimeStr(const char *fmt,time_t time = 0); * 根据unix时间戳获取本地时间 * @param sec unix时间戳 * @return tm结构体 + * Get local time based on Unix timestamp + * @param sec Unix timestamp + * @return tm structure + + * [AUTO-TRANSLATED:22a03a5b] */ struct tm getLocalTime(time_t sec); /** * 设置线程名 + * Set thread name + + * [AUTO-TRANSLATED:d0bcbcdc] */ void setThreadName(const char *name); /** * 获取线程名 + * Get thread name + + * [AUTO-TRANSLATED:99245fec] */ std::string getThreadName(); @@ -333,20 +387,32 @@ std::string getThreadName(); * 设置当前线程cpu亲和性 * @param i cpu索引,如果为-1,那么取消cpu亲和性 * @return 是否成功,目前只支持linux + * Set current thread CPU affinity + * @param i CPU index, if -1, cancel CPU affinity + * @return Whether successful, currently only supports Linux + + * [AUTO-TRANSLATED:9b3d6a83] */ bool setThreadAffinity(int i); /** * 根据typeid(class).name()获取类名 + * Get class name based on typeid(class).name() + + * [AUTO-TRANSLATED:7ac66c58] */ std::string demangle(const char *mangled); /** * 获取环境变量内容,以'$'开头 + * Get environment variable content, starting with '$' + + * [AUTO-TRANSLATED:c2c1689d] */ std::string getEnv(const std::string &key); -// 可以保存任意的对象 +// 可以保存任意的对象 [AUTO-TRANSLATED:e7c40bad] +//Can store any object class Any { public: using Ptr = std::shared_ptr; @@ -429,7 +495,8 @@ class Any { std::shared_ptr _data; }; -// 用于保存一些外加属性 +// 用于保存一些外加属性 [AUTO-TRANSLATED:cfbc20a3] +//Used to store some additional properties class AnyStorage : public std::unordered_map { public: AnyStorage() = default; diff --git a/src/Util/uv_errno.cpp b/src/Util/uv_errno.cpp index 1b365fcac..7aab002c4 100644 --- a/src/Util/uv_errno.cpp +++ b/src/Util/uv_errno.cpp @@ -60,7 +60,8 @@ int uv_translate_posix_error(int err) { return err; } switch (err) { - //为了兼容windows/unix平台,信号EINPROGRESS ,EAGAIN,EWOULDBLOCK,ENOBUFS 全部统一成EAGAIN处理 + //为了兼容windows/unix平台,信号EINPROGRESS ,EAGAIN,EWOULDBLOCK,ENOBUFS 全部统一成EAGAIN处理 [AUTO-TRANSLATED:aa58d626] + //To be compatible with Windows/Unix platforms, signals EINPROGRESS, EAGAIN, EWOULDBLOCK, ENOBUFS are all unified as EAGAIN for processing case ENOBUFS://在mac系统下实测发现会有此信号发生 case EINPROGRESS: case EWOULDBLOCK: err = EAGAIN; break; diff --git a/src/Util/uv_errno.h b/src/Util/uv_errno.h index e5e93f2af..4bc67b682 100644 --- a/src/Util/uv_errno.h +++ b/src/Util/uv_errno.h @@ -514,9 +514,11 @@ typedef enum { const char *uv_err_name(int err); const char *uv_strerror(int err); int uv_translate_posix_error(int err); -//netErr参数在windows平台下才有效 +//netErr参数在windows平台下才有效 [AUTO-TRANSLATED:4e619bdb] +//The netErr parameter is only valid on the Windows platform int get_uv_error(bool netErr = true); -//netErr参数在windows平台下才有效 +//netErr参数在windows平台下才有效 [AUTO-TRANSLATED:4e619bdb] +//The netErr parameter is only valid on the Windows platform const char *get_uv_errmsg(bool netErr = true); }//namespace toolkit