From 676d39d6a2ec18074f0570d1cfa1ce9a02e7d6fe Mon Sep 17 00:00:00 2001 From: Ayndpa Date: Tue, 18 Nov 2025 19:20:36 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E8=BF=9E=E6=8E=A5=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E7=9A=84=E4=BA=92=E6=96=A5=E9=94=81=EF=BC=8C=E5=A2=9E?= =?UTF-8?q?=E5=BC=BA=E5=A4=9A=E7=BA=BF=E7=A8=8B=E7=8E=AF=E5=A2=83=E4=B8=8B?= =?UTF-8?q?=E7=9A=84=E8=BF=9E=E6=8E=A5=E5=AE=89=E5=85=A8=E6=80=A7=EF=BC=9B?= =?UTF-8?q?=E6=9B=B4=E6=96=B0TCPClient=E4=BB=A5=E6=94=AF=E6=8C=81=E6=96=AD?= =?UTF-8?q?=E5=BC=80=E5=9B=9E=E8=B0=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- online_game_tool.cpp | 24 ++++++++++++++++-------- steam_message_handler.cpp | 16 +++++++++++++--- steam_message_handler.h | 3 ++- tcp/tcp_client.cpp | 11 ++++++++++- tcp/tcp_client.h | 3 +++ 5 files changed, 44 insertions(+), 13 deletions(-) diff --git a/online_game_tool.cpp b/online_game_tool.cpp index 7a10545..601a7d2 100644 --- a/online_game_tool.cpp +++ b/online_game_tool.cpp @@ -48,6 +48,7 @@ int g_currentVirtualPort = 0; std::vector connections; std::map clientMap; std::mutex clientMutex; +std::mutex connectionsMutex; // Add mutex for connections int localPort = 0; bool g_isHost = false; bool g_isClient = false; @@ -73,7 +74,10 @@ void OnSteamNetConnectionStatusChanged(SteamNetConnectionStatusChangedCallback_t { // Incoming connection, accept it SteamNetworkingSockets()->AcceptConnection(pInfo->m_hConn); - connections.push_back(pInfo->m_hConn); + { + std::lock_guard lockConn(connectionsMutex); + connections.push_back(pInfo->m_hConn); + } g_hConnection = pInfo->m_hConn; // Keep for backward compatibility if needed g_isConnected = true; std::cout << "Accepted incoming connection from " << pInfo->m_info.m_identityRemote.GetSteamID().ConvertToUint64() << std::endl; @@ -115,12 +119,15 @@ void OnSteamNetConnectionStatusChanged(SteamNetConnectionStatusChangedCallback_t g_isConnected = false; g_hConnection = k_HSteamNetConnection_Invalid; // Remove from connections - auto it = connections.begin(); - while (it != connections.end()) { - if (*it == pInfo->m_hConn) { - it = connections.erase(it); - } else { - ++it; + { + std::lock_guard lockConn(connectionsMutex); + auto it = connections.begin(); + while (it != connections.end()) { + if (*it == pInfo->m_hConn) { + it = connections.erase(it); + } else { + ++it; + } } } // Remove from userMap @@ -198,7 +205,7 @@ int main() { boost::asio::io_context io_context; // Create Steam Message Handler - SteamMessageHandler messageHandler(io_context, m_pInterface, connections, clientMap, clientMutex, server, g_isHost, localPort); + SteamMessageHandler messageHandler(io_context, m_pInterface, connections, clientMap, clientMutex, connectionsMutex, server, g_isHost, localPort); // Initialize GLFW if (!glfwInit()) { @@ -344,6 +351,7 @@ int main() { } { std::lock_guard lock(clientMutex); + std::lock_guard lockConn(connectionsMutex); ImGui::Text("连接的好友: %d", (int)connections.size()); ImGui::Text("活跃的TCP客户端: %d", (int)clientMap.size()); } diff --git a/steam_message_handler.cpp b/steam_message_handler.cpp index d098537..0dfcd8a 100644 --- a/steam_message_handler.cpp +++ b/steam_message_handler.cpp @@ -10,8 +10,8 @@ const char* CONTROL_PREFIX = "CONTROL:"; const size_t CONTROL_PREFIX_LEN = 8; -SteamMessageHandler::SteamMessageHandler(boost::asio::io_context& io_context, ISteamNetworkingSockets* interface, std::vector& connections, std::map& clientMap, std::mutex& clientMutex, std::unique_ptr& server, bool& g_isHost, int& localPort) - : io_context_(io_context), m_pInterface_(interface), connections_(connections), clientMap_(clientMap), clientMutex_(clientMutex), server_(server), g_isHost_(g_isHost), localPort_(localPort), running_(false) {} +SteamMessageHandler::SteamMessageHandler(boost::asio::io_context& io_context, ISteamNetworkingSockets* interface, std::vector& connections, std::map& clientMap, std::mutex& clientMutex, std::mutex& connectionsMutex, std::unique_ptr& server, bool& g_isHost, int& localPort) + : io_context_(io_context), m_pInterface_(interface), connections_(connections), clientMap_(clientMap), clientMutex_(clientMutex), connectionsMutex_(connectionsMutex), server_(server), g_isHost_(g_isHost), localPort_(localPort), running_(false) {} SteamMessageHandler::~SteamMessageHandler() { stop(); @@ -48,8 +48,13 @@ void SteamMessageHandler::run() { } void SteamMessageHandler::pollMessages() { + std::vector currentConnections; + { + std::lock_guard lockConn(connectionsMutex_); + currentConnections = connections_; + } std::lock_guard lock(clientMutex_); - for (auto conn : connections_) { + for (auto conn : currentConnections) { ISteamNetworkingMessage* pIncomingMsgs[10]; int numMsgs = m_pInterface_->ReceiveMessagesOnConnection(conn, pIncomingMsgs, 10); for (int i = 0; i < numMsgs; ++i) { @@ -72,6 +77,11 @@ void SteamMessageHandler::pollMessages() { std::lock_guard lock(clientMutex_); m_pInterface_->SendMessageToConnection(conn, data, size, k_nSteamNetworkingSend_Reliable, nullptr); }); + client->setDisconnectCallback([conn, this]() { + std::lock_guard lock(clientMutex_); + m_pInterface_->CloseConnection(conn, 0, nullptr, false); + std::cout << "Closed Steam connection due to TCP client disconnect" << std::endl; + }); clientMap_[conn] = client; std::cout << "Created TCP Client for connection on first message" << std::endl; } else { diff --git a/steam_message_handler.h b/steam_message_handler.h index 957dc51..660ac72 100644 --- a/steam_message_handler.h +++ b/steam_message_handler.h @@ -13,7 +13,7 @@ class SteamMessageHandler { public: - SteamMessageHandler(boost::asio::io_context& io_context, ISteamNetworkingSockets* interface, std::vector& connections, std::map& clientMap, std::mutex& clientMutex, std::unique_ptr& server, bool& g_isHost, int& localPort); + SteamMessageHandler(boost::asio::io_context& io_context, ISteamNetworkingSockets* interface, std::vector& connections, std::map& clientMap, std::mutex& clientMutex, std::mutex& connectionsMutex, std::unique_ptr& server, bool& g_isHost, int& localPort); ~SteamMessageHandler(); void start(); @@ -28,6 +28,7 @@ private: std::vector& connections_; std::map& clientMap_; std::mutex& clientMutex_; + std::mutex& connectionsMutex_; std::unique_ptr& server_; bool& g_isHost_; int& localPort_; diff --git a/tcp/tcp_client.cpp b/tcp/tcp_client.cpp index e16f1fd..efe7eff 100644 --- a/tcp/tcp_client.cpp +++ b/tcp/tcp_client.cpp @@ -1,7 +1,7 @@ #include "tcp_client.h" #include -TCPClient::TCPClient(const std::string& host, int port) : host_(host), port_(port), connected_(false), socket_(std::make_shared(io_context_)), work_(boost::asio::make_work_guard(io_context_)), buffer_(1024) {} +TCPClient::TCPClient(const std::string& host, int port) : host_(host), port_(port), connected_(false), disconnected_(false), socket_(std::make_shared(io_context_)), work_(boost::asio::make_work_guard(io_context_)), buffer_(1024) {} TCPClient::~TCPClient() { disconnect(); } @@ -26,6 +26,11 @@ bool TCPClient::connect() { } void TCPClient::disconnect() { + if (disconnected_) return; + disconnected_ = true; + if (disconnectCallback_) { + disconnectCallback_(); + } connected_ = false; io_context_.stop(); if (clientThread_.joinable()) { @@ -59,6 +64,10 @@ void TCPClient::setReceiveCallback(std::function call receiveCallbackBytes_ = callback; } +void TCPClient::setDisconnectCallback(std::function callback) { + disconnectCallback_ = callback; +} + void TCPClient::start_read() { socket_->async_read_some(boost::asio::buffer(buffer_), [this](const boost::system::error_code& error, std::size_t bytes_transferred) { handle_read(error, bytes_transferred); diff --git a/tcp/tcp_client.h b/tcp/tcp_client.h index 25eafa0..8e8406e 100644 --- a/tcp/tcp_client.h +++ b/tcp/tcp_client.h @@ -21,6 +21,7 @@ public: void send(const char* data, size_t size); void setReceiveCallback(std::function callback); void setReceiveCallback(std::function callback); + void setDisconnectCallback(std::function callback); private: void start_read(); @@ -29,6 +30,7 @@ private: std::string host_; int port_; bool connected_; + bool disconnected_; boost::asio::io_context io_context_; boost::asio::executor_work_guard work_; std::shared_ptr socket_; @@ -36,5 +38,6 @@ private: std::mutex socketMutex_; std::function receiveCallback_; std::function receiveCallbackBytes_; + std::function disconnectCallback_; std::vector buffer_; }; \ No newline at end of file