From d8590ac453baa4afd8251acd49da0cc87db97e5e Mon Sep 17 00:00:00 2001 From: alex Date: Tue, 17 Sep 2024 09:47:04 +0800 Subject: [PATCH] Translate comments in src/Network/Socket.cpp --- src/Network/Socket.cpp | 201 +++++++++++++++++++++++++++-------------- 1 file changed, 134 insertions(+), 67 deletions(-) diff --git a/src/Network/Socket.cpp b/src/Network/Socket.cpp index 26a85a45..a760e073 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 to 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] + // Block 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(); @@ -315,14 +328,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 exceptions here to prevent data from not being read thoroughly, and epoll edge trigger failure issues LOCK_GUARD(_mtx_event); _on_multi_read(&buf, &addr, count); } catch (std::exception &ex) { @@ -349,7 +364,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 obtain fd-related information strong_self->closeSock(false); }); return true; @@ -376,7 +392,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 time the send did not specify the target address, but the target is specified through bindPeerAddr addr = (struct sockaddr *)_udp_send_dst.get(); addr_len = SockUtil::get_sock_len(addr); } @@ -407,17 +424,21 @@ int Socket::flushAll() { LOCK_GUARD(_mtx_sock_fd); if (!_sock_fd) { - // 如果已断开连接或者发送超时 + // 如果已断开连接或者发送超时 [AUTO-TRANSLATED:2e25a648] + // If the connection is already disconnected or the send 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 time limit, then disconnect the socket connection emitErr(SockException(Err_other, "socket send timeout")); return -1; } @@ -537,33 +558,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 connections 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] + // Maybe too many file descriptors are open: UV_EMFILE/UV_ENFILE #if (defined(HAS_EPOLL) && !defined(_WIN32)) || defined(HAS_KQUEUE) - // 边缘触发,还需要手动再触发accept事件, + // 边缘触发,还需要手动再触发accept事件, [AUTO-TRANSLATED:85fa9030] + // Edge trigger, still 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 is an idle fd 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 then manually trigger onAccept (only after EAGAIN reads empty can it be triggered again through epoll) 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 a level trigger, it will automatically enter the onAccept function again next time return -1; #endif } @@ -578,9 +607,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 socket from not accepting thoroughly, epoll edge trigger failure issues 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(); @@ -589,21 +620,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, that is, 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 up the fd, 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 and then the onRead event) if (!peer_sock->attachEvent(sock)) { - // 加入poll监听失败,触发onErr事件,通知该Socket无效 + // 加入poll监听失败,触发onErr事件,通知该Socket无效 [AUTO-TRANSLATED:e81fd478] + // Failed to add to poll monitoring, trigger the onErr event, and 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) { @@ -612,9 +648,11 @@ int Socket::onAccept(const SockNum::Ptr &sock, int event) noexcept { }); try { - // 此处捕获异常,目的是防止socket未accept尽,epoll边沿触发失效的问题 + // 此处捕获异常,目的是防止socket未accept尽,epoll边沿触发失效的问题 [AUTO-TRANSLATED:523d496d] + // Catch the exception here to prevent the socket from not being accepted, and the epoll edge trigger is invalid LOCK_GUARD(_mtx_event); - // 先触发onAccept事件,此时应该监听该Socket的onRead等事件 + // 先触发onAccept事件,此时应该监听该Socket的onRead等事件 [AUTO-TRANSLATED:29734871] + // First trigger the onAccept event, at this time, you should listen to the onRead event of the Socket _on_accept(peer_sock, completed); } catch (std::exception &ex) { ErrorL << "Exception occurred when emit on_accept: " << ex.what(); @@ -688,7 +726,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); @@ -699,14 +738,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 the data in the primary cache LOCK_GUARD(_mtx_send_buf_waiting); if (!_send_buf_waiting.empty()) { - // 把一级缓中数数据放置到二级缓存中并清空 + // 把一级缓中数数据放置到二级缓存中并清空 [AUTO-TRANSLATED:4884aa58] + // Put the data in the primary cache into the secondary 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 send rate _send_speed += buffer->size(); } LOCK_GUARD(_mtx_event); @@ -718,10 +760,13 @@ bool Socket::flushData(const SockNum::Ptr &sock, bool poller_thread) { break; } } - // 如果一级缓存也为空,那么说明所有数据均写入socket了 + // 如果一级缓存也为空,那么说明所有数据均写入socket了 [AUTO-TRANSLATED:6ae9ef8a] + // If the primary 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 monitoring of the writable event + // 那么在数据列队清空的情况下,我们需要关闭监听以免触发无意义的事件回调 [AUTO-TRANSLATED:0fb35573] + // So, in the case where the data queue is empty, we need to close the monitoring to avoid triggering meaningless event callbacks stopWriteAbleEvent(sock); onFlushed(); } @@ -733,55 +778,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 send is successful if (packet->empty()) { - // 全部发送成功 + // 全部发送成功 [AUTO-TRANSLATED:38a7d0ac] + // All send is successful send_buf_sending_tmp.pop_front(); continue; } - // 部分发送成功 + // 部分发送成功 [AUTO-TRANSLATED:bd6609dd] + // Part of the send is successful 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 monitoring of the writable event, so we don't need to add monitoring again startWriteAbleEvent(sock); } break; } - // 一个都没发送成功 + // 一个都没发送成功 [AUTO-TRANSLATED:a3b4f257] + // None of the sends were successful 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 been added to the monitoring of the writable event, so we don't need to add monitoring again startWriteAbleEvent(sock); } break; } - // 其他错误代码,发生异常 + // 其他错误代码,发生异常 [AUTO-TRANSLATED:14cca084] + // Other error codes, exceptions occur 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 is not fully sent, indicating that the socket is not writable, return directly return true; } - // 二级缓存已经全部发送完毕,说明该socket还可写,我们尝试继续写 - // 如果是poller线程,我们尝试再次写一次(因为可能其他线程调用了send函数又有新数据了) + // 二级缓存已经全部发送完毕,说明该socket还可写,我们尝试继续写 [AUTO-TRANSLATED:2c2bc316] + // The secondary cache has been fully sent, indicating that the socket is still writable, we try to continue writing + // 如果是poller线程,我们尝试再次写一次(因为可能其他线程调用了send函数又有新数据了) [AUTO-TRANSLATED:392684a8] + // If it is 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; } @@ -799,23 +859,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) {}); @@ -827,7 +891,8 @@ void Socket::enableRecv(bool enabled) { } _enable_recv = enabled; int read_flag = _enable_recv ? EventPoller::Event_Read : 0; - // 可写时,不监听可写事件 + // 可写时,不监听可写事件 [AUTO-TRANSLATED:6a50e751] + // When writable, do not listen for writable events int send_flag = _sendable ? 0 : EventPoller::Event_Write; _poller->modifyEvent(rawFD(), read_flag | send_flag | EventPoller::Event_Error); } @@ -889,11 +954,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 binding, 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);