From 891bc59c12bd62e4232c34c98b2e3cbaed0e7061 Mon Sep 17 00:00:00 2001 From: lanthora Date: Wed, 17 Sep 2025 17:31:48 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20Windows=20UDP=20=E8=BF=9E?= =?UTF-8?q?=E6=8E=A5=E9=87=8D=E7=BD=AE=E5=AF=BC=E8=87=B4=E7=9A=84=E5=B4=A9?= =?UTF-8?q?=E6=BA=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 2 +- candy/src/peer/manager.cc | 36 +++++++++++++++++++++++------------- candy/src/peer/manager.h | 2 +- 3 files changed, 25 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index eb1fb105..65079265 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.16) -project(Candy VERSION 6.1.1) +project(Candy VERSION 6.1.2) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) diff --git a/candy/src/peer/manager.cc b/candy/src/peer/manager.cc index 68169de9..0ed07c4a 100644 --- a/candy/src/peer/manager.cc +++ b/candy/src/peer/manager.cc @@ -342,7 +342,9 @@ int PeerManager::initSocket() { this->pollThread = std::thread([&]() { spdlog::debug("start thread: peer manager poll"); while (getClient().isRunning()) { - poll(); + if (poll()) { + break; + } } getClient().shutdown(); spdlog::debug("stop thread: peer manager poll"); @@ -516,24 +518,32 @@ void PeerManager::handleRouteMessage(std::string buffer, const SocketAddress &ad } } -void PeerManager::poll() { +int PeerManager::poll() { using Poco::Net::Socket; using Poco::Net::SocketAddress; - if (this->socket.poll(Poco::Timespan(1, 0), Poco::Net::Socket::SELECT_READ)) { - std::string buffer(1500, 0); - SocketAddress address; - auto size = this->socket.receiveFrom(buffer.data(), buffer.size(), address); - if (size > 0) { - buffer.resize(size); - - if (this->stun.address == address) { - handleStunResponse(buffer); - } else if (auto plaintext = decrypt(buffer)) { - handleMessage(std::move(*plaintext), address); + try { + if (this->socket.poll(Poco::Timespan(1, 0), Poco::Net::Socket::SELECT_READ)) { + std::string buffer(1500, 0); + SocketAddress address; + auto size = this->socket.receiveFrom(buffer.data(), buffer.size(), address); + if (size > 0) { + buffer.resize(size); + + if (this->stun.address == address) { + handleStunResponse(buffer); + } else if (auto plaintext = decrypt(buffer)) { + handleMessage(std::move(*plaintext), address); + } } } + } catch (Poco::Net::ConnectionResetException &e) { + // 忽略 UDP 的连接 Reset, Windows 特有的问题 + } catch (std::exception &e) { + spdlog::warn("peer_manager poll failed: {}", e.what()); + return -1; } + return 0; } std::optional PeerManager::decrypt(const std::string &ciphertext) { diff --git a/candy/src/peer/manager.h b/candy/src/peer/manager.h index 94a7d68d..823b4a65 100644 --- a/candy/src/peer/manager.h +++ b/candy/src/peer/manager.h @@ -124,7 +124,7 @@ class PeerManager { void handleForwardMessage(std::string buffer, const SocketAddress &address); void handleDelayMessage(std::string buffer, const SocketAddress &address); void handleRouteMessage(std::string buffer, const SocketAddress &address); - void poll(); + int poll(); std::optional decrypt(const std::string &ciphertext); std::shared_ptr decryptCtx;