From 0ed55b478d1898bd583b7fb164e0c3bbe9a3955d Mon Sep 17 00:00:00 2001 From: taynpg Date: Sat, 10 May 2025 14:48:42 +0800 Subject: [PATCH] =?UTF-8?q?server=EF=BC=9A=E6=9C=8D=E5=8A=A1=E7=AB=AF?= =?UTF-8?q?=E8=BD=AC=E5=8F=91=E5=8A=9F=E8=83=BD=E5=9F=BA=E6=9C=AC=E5=AE=8C?= =?UTF-8?q?=E6=88=90=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/settings.json | 3 +- CMakeLists.txt | 2 +- ClientCore/CMakeLists.txt | 2 +- Information/InfoCommunicate.hpp | 7 +- Protocol/CMakeLists.txt | 2 +- Protocol/Communicate.cxx | 47 +++++++++----- Protocol/Communicate.h | 6 +- RelayServer/CMakeLists.txt | 2 +- RelayServer/RelayServer.cxx | 111 +++++++++++++++++++++++++++++--- RelayServer/RelayServer.h | 31 ++++++++- UserInterface/CMakeLists.txt | 2 +- Util/CMakeLists.txt | 2 +- 12 files changed, 182 insertions(+), 35 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 346a0ab..3a5c2c4 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -121,6 +121,7 @@ "typeindex": "cpp", "valarray": "cpp", "charconv": "cpp", - "compare": "cpp" + "compare": "cpp", + "format": "cpp" } } \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 768f099..d49733d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.16) project(RelayFile VERSION 0.1.0 LANGUAGES CXX) -set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_PREFIX_PATH "D:/Program/Dev/wxWidgets") diff --git a/ClientCore/CMakeLists.txt b/ClientCore/CMakeLists.txt index 5b7506c..3a629c5 100644 --- a/ClientCore/CMakeLists.txt +++ b/ClientCore/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.16) project(ClientCore LANGUAGES CXX) -set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) find_package(wxWidgets CONFIG REQUIRED) diff --git a/Information/InfoCommunicate.hpp b/Information/InfoCommunicate.hpp index 09d6737..34acfd3 100644 --- a/Information/InfoCommunicate.hpp +++ b/Information/InfoCommunicate.hpp @@ -4,20 +4,23 @@ #include #include #include +#include enum MessageType { MSG_TYPE_ASK_CLIENTS = 1, + MSG_TYPE_FORWORD_FAILED }; struct InfoCommunicate { MessageType type; + std::string fromID; std::string toID; std::string UUID; std::string data; - char mark{}; + uint8_t mark{}; template void serialize(Archive& archive) { - archive(CEREAL_NVP(type), CEREAL_NVP(toID), CEREAL_NVP(UUID), CEREAL_NVP(data), CEREAL_NVP(mark)); + archive(CEREAL_NVP(type), CEREAL_NVP(fromID), CEREAL_NVP(toID), CEREAL_NVP(UUID), CEREAL_NVP(data), CEREAL_NVP(mark)); } }; diff --git a/Protocol/CMakeLists.txt b/Protocol/CMakeLists.txt index d10b21e..d9bd30a 100644 --- a/Protocol/CMakeLists.txt +++ b/Protocol/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.16) project(Protocol LANGUAGES CXX) -set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) find_package(wxWidgets CONFIG REQUIRED) diff --git a/Protocol/Communicate.cxx b/Protocol/Communicate.cxx index e329a97..563fbc6 100644 --- a/Protocol/Communicate.cxx +++ b/Protocol/Communicate.cxx @@ -10,6 +10,7 @@ Communicate::Communicate() /* 【 transm TCP 数据协议 】 header 2 char: 0xFF 0xFE + unpack 1 char; from 32 char: to 32 char: len 4 char: @@ -26,25 +27,26 @@ FrameBuffer* Communicate::ParseBuffer(MutBuffer& buffer) } int len = 0; - std::memcpy(&len, buffer.GetData() + find + sizeof(gHeader) + 64, sizeof(len)); - if (buffer.Length() < (find + sizeof(gHeader) + 64 + len + sizeof(len) + sizeof(gTail)) || len < 0) { + std::memcpy(&len, buffer.GetData() + find + sizeof(gHeader) + sizeof(uint8_t) + 64, sizeof(len)); + if (buffer.Length() < (find + sizeof(gHeader) + sizeof(uint8_t) + 64 + len + sizeof(len) + sizeof(gTail)) || len < 0) { return frame; } - if (std::memcmp(buffer.GetData() + find + sizeof(gHeader) + 64 + sizeof(len) + len, gTail, sizeof(gTail)) != 0) { + if (std::memcmp(buffer.GetData() + find + sizeof(gHeader) + sizeof(uint8_t) + 64 + sizeof(len) + len, gTail, sizeof(gTail)) != + 0) { return frame; } frame = new FrameBuffer(); - frame->fid = std::string(buffer.GetData() + find + sizeof(gHeader), 32); - frame->tid = std::string(buffer.GetData() + find + sizeof(gHeader) + 32, 32); + frame->fid = std::string(buffer.GetData() + find + sizeof(gHeader) + sizeof(uint8_t), 32); + frame->tid = std::string(buffer.GetData() + find + sizeof(gHeader) + sizeof(uint8_t) + 32, 32); if (len > 0) { - frame->data = new char[len]; - std::memcpy(frame->data, buffer.GetData() + find + sizeof(gHeader) + 64 + sizeof(len), len); + frame->dataMut = new char[len]; + std::memcpy(frame->dataMut, buffer.GetData() + find + sizeof(gHeader) + sizeof(uint8_t) + 64 + sizeof(len), len); frame->len = len; } - buffer.RemoveOf(0, find + sizeof(gHeader) + 64 + len + sizeof(len) + sizeof(gTail)); + buffer.RemoveOf(0, find + sizeof(gHeader) + sizeof(uint8_t) + 64 + len + sizeof(len) + sizeof(gTail)); return frame; } @@ -53,24 +55,39 @@ bool Communicate::PackBuffer(FrameBuffer* frame, char** buf, int& len) if (frame == nullptr) { return false; } - if (frame->data == nullptr) { + const char* dataPtr = nullptr; + if (frame->dataMut == nullptr) { frame->len = 0; } - len = sizeof(gHeader) + 64 + sizeof(len) + frame->len + sizeof(gTail); + if (frame->dataConst) { + dataPtr = frame->dataConst; + } else { + dataPtr = frame->dataMut; + } + len = sizeof(gHeader) + sizeof(uint8_t) + 64 + sizeof(len) + frame->len + sizeof(gTail); *buf = new char[len]; std::memcpy(*buf, gHeader, sizeof(gHeader)); - std::memcpy(*buf + sizeof(gHeader), frame->fid.c_str(), 32); - std::memcpy(*buf + sizeof(gHeader) + 32, frame->tid.c_str(), 32); - std::memcpy(*buf + sizeof(gHeader) + 64, &frame->len, sizeof(len)); + std::memcpy(*buf + sizeof(gHeader), &frame->unpack, sizeof(uint8_t)); + std::memcpy(*buf + sizeof(gHeader) + sizeof(uint8_t), frame->fid.c_str(), 32); + std::memcpy(*buf + sizeof(gHeader) + sizeof(uint8_t) + 32, frame->tid.c_str(), 32); + std::memcpy(*buf + sizeof(gHeader) + sizeof(uint8_t) + 64, &frame->len, sizeof(len)); if (frame->len > 0) { - std::memcpy(*buf + sizeof(gHeader) + 64 + sizeof(len), frame->data, frame->len); + std::memcpy(*buf + sizeof(gHeader) + 64 + sizeof(len), dataPtr, frame->len); } std::memcpy(*buf + sizeof(gHeader) + 64 + sizeof(len) + frame->len, gTail, sizeof(gTail)); + frame->dataConst = nullptr; return true; } +FrameBuffer::FrameBuffer() +{ + dataConst = nullptr; + dataMut = nullptr; + len = 0; +} + FrameBuffer::~FrameBuffer() { - delete[] data; + delete[] dataMut; len = 0; } diff --git a/Protocol/Communicate.h b/Protocol/Communicate.h index 65c4d48..62480a4 100644 --- a/Protocol/Communicate.h +++ b/Protocol/Communicate.h @@ -2,12 +2,16 @@ #define COMMUNICATE_H #include +#include struct FrameBuffer { + FrameBuffer(); ~FrameBuffer(); + uint8_t unpack{}; std::string fid; std::string tid; - char* data{}; + const char* dataConst; + char* dataMut; int len{}; }; diff --git a/RelayServer/CMakeLists.txt b/RelayServer/CMakeLists.txt index a9aa809..633302c 100644 --- a/RelayServer/CMakeLists.txt +++ b/RelayServer/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.16) project(RelayServer LANGUAGES CXX) -set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) find_package(wxWidgets CONFIG REQUIRED) diff --git a/RelayServer/RelayServer.cxx b/RelayServer/RelayServer.cxx index 5c87204..b1d956c 100644 --- a/RelayServer/RelayServer.cxx +++ b/RelayServer/RelayServer.cxx @@ -1,6 +1,5 @@ #include "RelayServer.h" -#include -#include +#include RemoteServer::RemoteServer() { @@ -8,7 +7,7 @@ RemoteServer::RemoteServer() bool RemoteServer::Init(const wxString& ip, unsigned short port) { - thRun_= true; + thRun_ = true; wxIPV4address addr; if (!addr.Hostname(ip)) { @@ -27,7 +26,7 @@ bool RemoteServer::Init(const wxString& ip, unsigned short port) return false; } wxLogMessage(wxT("Server socket created on %s:%d"), addr.IPAddress(), addr.Service()); - //wxLogInfo(wxT("Server socket created on %s:%d"), addr.IPAddress(), addr.Service()); + // wxLogInfo(wxT("Server socket created on %s:%d"), addr.IPAddress(), addr.Service()); serverId_ = wxNewId(); server_->SetFlags(wxSOCKET_WAITALL); @@ -118,11 +117,107 @@ void RemoteServer::thClientThread(const std::shared_ptr& wxSock, c if (!frame) { break; } - std::stringstream ss; - ss.write(frame->data, frame->len); - cereal::BinaryInputArchive inputArchive(ss); - inputArchive(info); + if (frame->unpack != 0) { + std::stringstream ss; + ss.write(frame->dataMut, frame->len); + cereal::BinaryInputArchive inputArchive(ss); + inputArchive(info); + Reply(client->wxSock, info); + delete frame; + continue; + } + Forword(client->wxSock, frame); delete frame; } } } + +bool RemoteServer::Forword(const sockPtr& wxSock, FrameBuffer* buf) +{ + std::shared_ptr fcl = nullptr; + std::shared_ptr tcl = nullptr; + + { + std::shared_lock lock(clientsMutex_); + if (clients_.count(buf->fid)) { + fcl = clients_[buf->fid]; + } + if (clients_.count(buf->tid)) { + tcl = clients_[buf->tid]; + } + } + + bool farward = false; + if (tcl) { + farward = Send(tcl->wxSock, buf); + } + if (farward) { + return true; + } + if (fcl) { + RpyForwordFailed(fcl->wxSock); + } + return farward; +} + +bool RemoteServer::Reply(const sockPtr& wxSock, InfoCommunicate& info) +{ + switch (info.type) { + case MSG_TYPE_ASK_CLIENTS: { + std::swap(info.fromID, info.toID); + info.fromID = strID_; + RpyOnline(wxSock); + break; + } + default: + break; + } + wxLogWarning(_("Unknow message type: %d"), info.type); + return false; +} + +bool RemoteServer::RpyOnline(const sockPtr& wxSock) +{ + InfoClientVec infoClients; + { + std::shared_lock lock(clientsMutex_); + for (const auto& client : clients_) { + InfoClient infoClient; + infoClient.id = client.first; + infoClient.name = client.second->name; + infoClients.vec.push_back(infoClient); + } + } + std::stringstream ss; + cereal::BinaryOutputArchive archive(ss); + archive(infoClients); + return Send(wxSock, infoClients); +} + +bool RemoteServer::RpyForwordFailed(const sockPtr& wxSock) +{ + InfoCommunicate info; + info.type = MSG_TYPE_FORWORD_FAILED; + return Send(wxSock, info); +} + +bool RemoteServer::Send(const sockPtr& wxSock, FrameBuffer* buf) +{ + if (buf == nullptr) { + return false; + } + char* od = nullptr; + int odLen = 0; + if (!Communicate::PackBuffer(buf, &od, odLen)) { + return false; + } + + wxSock->Write(od, odLen); + if (wxSock->Error()) { + delete[] od; + wxLogError(wxT("Send error: %s"), wxSock->LastError()); + return false; + } + delete[] od; + return true; +} \ No newline at end of file diff --git a/RelayServer/RelayServer.h b/RelayServer/RelayServer.h index b85a598..35a2cc9 100644 --- a/RelayServer/RelayServer.h +++ b/RelayServer/RelayServer.h @@ -1,6 +1,9 @@ #ifndef REMOTE_SERVER_H #define REMOTE_SERVER_H +#include +#include + #include #include #include @@ -17,12 +20,14 @@ // constexpr int gBufferSize = 1024 * 1024; constexpr int gBufferSize = 256; using highClock_t = std::chrono::time_point; +using sockPtr = std::shared_ptr; struct TranClient { - std::shared_ptr wxSock; - std::array buf; + sockPtr wxSock; MutBuffer buffer; int64_t onlineTime; + std::string name; highClock_t lastRecvTime; + std::array buf; }; class RemoteServer : public wxEvtHandler @@ -37,9 +42,31 @@ public: private: void OnServerEvent(wxSocketEvent& event); void thClientThread(const std::shared_ptr& wxSock, const wxString& id); + bool Forword(const sockPtr& wxSock, FrameBuffer* buf); + bool Reply(const sockPtr& wxSock, InfoCommunicate& info); + +private: + bool RpyOnline(const sockPtr& wxSock); + bool RpyForwordFailed(const sockPtr& wxSock); + +private: + template bool Send(const sockPtr& wxSock, const T& info) + { + std::stringstream ss; + cereal::BinaryOutputArchive archive(ss); + archive(info); + + auto buf = std::make_shared(); + buf->dataConst = ss.view().data(); + buf->len = ss.str().size(); + + return Send(wxSock, buf.get()); + } + bool Send(const sockPtr& wxSock, FrameBuffer* buf); private: bool thRun_{false}; + std::string strID_; wxWindowID serverId_; std::shared_mutex clientsMutex_; std::unique_ptr server_; diff --git a/UserInterface/CMakeLists.txt b/UserInterface/CMakeLists.txt index b2715e6..8b79fc5 100644 --- a/UserInterface/CMakeLists.txt +++ b/UserInterface/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.16) project(RelayFile LANGUAGES CXX) -set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) find_package(wxWidgets CONFIG REQUIRED) diff --git a/Util/CMakeLists.txt b/Util/CMakeLists.txt index 6f1b32e..991949d 100644 --- a/Util/CMakeLists.txt +++ b/Util/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.16) project(Util LANGUAGES CXX) -set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) find_package(wxWidgets CONFIG REQUIRED)