update:服务端代码进度。

This commit is contained in:
taynpg 2025-05-10 01:25:02 +08:00
parent 797ac91455
commit cb125d20f4
8 changed files with 237 additions and 17 deletions

View File

@ -0,0 +1,24 @@
#ifndef INFOCOMMUNICATE_HPP
#define INFOCOMMUNICATE_HPP
#include <cereal/archives/binary.hpp>
#include <cereal/types/memory.hpp>
#include <cereal/types/vector.hpp>
enum MessageType {
MSG_TYPE_ASK_CLIENTS = 1,
};
struct InfoCommunicate {
MessageType type;
std::string toID;
std::string UUID;
std::string data;
char mark{};
template <class Archive> void serialize(Archive& archive)
{
archive(CEREAL_NVP(type), CEREAL_NVP(toID), CEREAL_NVP(UUID), CEREAL_NVP(data), CEREAL_NVP(mark));
}
};
#endif // INFOCOMMUNICATE_HPP

View File

@ -12,4 +12,5 @@ Communicate.cxx
)
add_library(Protocol STATIC ${MSOURCES})
target_link_libraries(Protocol PRIVATE wx::base wx::core)
target_link_libraries(Protocol PRIVATE wx::base wx::core Util)
target_include_directories(Protocol PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})

View File

@ -1,5 +1,76 @@
#include "Communicate.h"
constexpr unsigned char gHeader[] = {0xFF, 0xFE};
constexpr unsigned char gTail[] = {0xFF, 0xFF};
Communicate::Communicate()
{
}
}
/*
transm TCP
header 2 char: 0xFF 0xFE
from 32 char:
to 32 char:
len 4 char:
data xxxxx:
tail 2 char: 0xFF 0xFF
*/
FrameBuffer* Communicate::ParseBuffer(MutBuffer& buffer)
{
FrameBuffer* frame = nullptr;
int find = buffer.IndexOf((const char*)gHeader, sizeof(gHeader));
if (find < 0) {
return frame;
}
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) {
return frame;
}
if (std::memcmp(buffer.GetData() + find + sizeof(gHeader) + 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);
if (len > 0) {
frame->data = new char[len];
std::memcpy(frame->data, buffer.GetData() + find + sizeof(gHeader) + 64 + sizeof(len), len);
frame->len = len;
}
buffer.RemoveOf(0, find + sizeof(gHeader) + 64 + len + sizeof(len) + sizeof(gTail));
return frame;
}
bool Communicate::PackBuffer(FrameBuffer* frame, char** buf, int& len)
{
if (frame == nullptr) {
return false;
}
if (frame->data == nullptr) {
frame->len = 0;
}
len = sizeof(gHeader) + 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));
if (frame->len > 0) {
std::memcpy(*buf + sizeof(gHeader) + 64 + sizeof(len), frame->data, frame->len);
}
std::memcpy(*buf + sizeof(gHeader) + 64 + sizeof(len) + frame->len, gTail, sizeof(gTail));
return true;
}
FrameBuffer::~FrameBuffer()
{
delete[] data;
len = 0;
}

View File

@ -1,10 +1,24 @@
#ifndef COMMUNICATE_H
#define COMMUNICATE_H
#include <Util.h>
struct FrameBuffer {
~FrameBuffer();
std::string fid;
std::string tid;
char* data{};
int len{};
};
class Communicate
{
public:
Communicate();
public:
static FrameBuffer* ParseBuffer(MutBuffer& buffer);
static bool PackBuffer(FrameBuffer* frame, char** buf, int& len);
};
#endif // COMMUNICATE_H

View File

@ -13,5 +13,5 @@ main.cxx
)
add_executable(RelayServer ${MSOURCES})
target_link_libraries(RelayServer PRIVATE wx::base wx::core Util)
set_target_properties(RelayServer PROPERTIES WIN32_EXECUTABLE TRUE)
target_link_libraries(RelayServer PRIVATE wx::base wx::core Util Protocol wx::net)
# set_target_properties(RelayServer PROPERTIES WIN32_EXECUTABLE TRUE)

View File

@ -1,4 +1,6 @@
#include "RelayServer.h"
#include <Communicate.h>
#include <InfoCommunicate.hpp>
RemoteServer::RemoteServer()
{
@ -6,18 +8,121 @@ RemoteServer::RemoteServer()
bool RemoteServer::Init(const wxString& ip, unsigned short port)
{
return false;
thRun_= true;
wxIPV4address addr;
if (!addr.Hostname(ip)) {
wxLogError(wxT("Invalid IP address: %s"), ip);
return false;
}
addr.Service(port);
server_ = std::make_unique<wxSocketServer>(addr);
if (!server_->IsOk()) {
wxLogError(wxT("Failed to create server socket."));
return false;
}
if (!server_->GetLocal(addr)) {
wxLogError(wxT("Failed to get local address."));
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());
serverId_ = wxNewId();
server_->SetFlags(wxSOCKET_WAITALL);
server_->SetEventHandler(*this, serverId_);
server_->SetNotify(wxSOCKET_CONNECTION_FLAG | wxSOCKET_LOST_FLAG);
server_->Notify(true);
Bind(wxEVT_SOCKET, &RemoteServer::OnServerEvent, this, serverId_);
return true;
}
int RemoteServer::Run()
{
return 0;
wxEventLoop loop;
return loop.Run();
}
void RemoteServer::OnServerEvent(wxSocketEvent& event)
{
auto* sock = event.GetSocket();
switch (event.GetSocketEvent()) {
case wxSOCKET_CONNECTION: {
auto newer = std::shared_ptr<wxSocketBase>(server_->Accept(false));
if (!newer) {
wxLogError(wxT("Failed to accept client connection."));
return;
}
wxIPV4address addr;
newer->GetPeer(addr);
wxString id = wxString::Format("%s:%d", addr.IPAddress(), addr.Service());
wxLogMessage(wxT("Client connected: %s"), id);
std::unique_lock<std::shared_mutex> lock(clientsMutex_);
auto client = std::make_shared<TranClient>();
client->wxSock = newer;
client->onlineTime =
std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
client->lastRecvTime = std::chrono::high_resolution_clock::now();
clients_[id] = client;
threads_[id] = std::thread(&RemoteServer::thClientThread, this, newer, id);
break;
}
case wxSOCKET_LOST: {
wxIPV4address addr;
sock->GetPeer(addr);
wxString id = wxString::Format("%s:%d", addr.IPAddress(), addr.Service());
wxLogMessage(wxT("Client disconnected: %s"), id);
std::unique_lock<std::shared_mutex> lock(clientsMutex_);
if (clients_.find(id) != clients_.end()) {
clients_.erase(id);
}
if (threads_.find(id) != threads_.end()) {
threads_[id].detach();
threads_.erase(id);
}
break;
}
default:
break;
}
}
void RemoteServer::thClientThread(const std::shared_ptr<wxSocketBase>& wxSock, const wxString& id)
{
wxLogMessage(wxT("Client thread started: %s"), id);
std::shared_ptr<TranClient> client = nullptr;
{
std::shared_lock<std::shared_mutex> lock(clientsMutex_);
client = clients_[id];
}
InfoCommunicate info;
while (thRun_) {
wxSock->Read(client->buf.data(), gBufferSize);
auto br = wxSock->LastCount();
if (br == 0) {
wxLogMessage(wxT("Client disconnected: %s"), id);
break;
} else if (wxSock->Error()) {
wxLogMessage(wxT("%s Client error: %s"), id, wxSock->LastError());
break;
}
client->buffer.Push(client->buf.data(), br);
while (true) {
auto* frame = Communicate::ParseBuffer(client->buffer);
if (!frame) {
break;
}
std::stringstream ss;
ss.write(frame->data, frame->len);
cereal::BinaryInputArchive inputArchive(ss);
inputArchive(info);
delete frame;
}
}
}

View File

@ -14,9 +14,12 @@
#include <wx/socket.h>
#include <wx/wx.h>
// constexpr int gBufferSize = 1024 * 1024;
constexpr int gBufferSize = 256;
using highClock_t = std::chrono::time_point<std::chrono::high_resolution_clock>;
struct TranClient {
std::shared_ptr<wxSocketBase> wxSock;
std::array<char, gBufferSize> buf;
MutBuffer buffer;
int64_t onlineTime;
highClock_t lastRecvTime;
@ -36,6 +39,7 @@ private:
void thClientThread(const std::shared_ptr<wxSocketBase>& wxSock, const wxString& id);
private:
bool thRun_{false};
wxWindowID serverId_;
std::shared_mutex clientsMutex_;
std::unique_ptr<wxSocketServer> server_;

View File

@ -1,14 +1,15 @@
#include "RelayServer.h"
class RelayServerApp : public wxApp
int main()
{
public:
bool OnInit() override;
};
bool RelayServerApp::OnInit()
{
return true;
}
wxIMPLEMENT_APP(RelayServerApp);
wxInitializer initializer;
if (!initializer.IsOk()) {
fprintf(stderr, "Failed to initialize the wxWidgets library, aborting.");
return -1;
}
auto server_ = std::make_unique<RemoteServer>();
if (server_->Init("127.0.0.1", 8080)) {
server_->Run();
}
return 0;
}