update:服务端代码进度。
This commit is contained in:
parent
797ac91455
commit
cb125d20f4
24
Information/InfoCommunicate.hpp
Normal file
24
Information/InfoCommunicate.hpp
Normal 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
|
@ -12,4 +12,5 @@ Communicate.cxx
|
|||||||
)
|
)
|
||||||
|
|
||||||
add_library(Protocol STATIC ${MSOURCES})
|
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})
|
@ -1,5 +1,76 @@
|
|||||||
#include "Communicate.h"
|
#include "Communicate.h"
|
||||||
|
|
||||||
|
constexpr unsigned char gHeader[] = {0xFF, 0xFE};
|
||||||
|
constexpr unsigned char gTail[] = {0xFF, 0xFF};
|
||||||
|
|
||||||
Communicate::Communicate()
|
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;
|
||||||
|
}
|
||||||
|
@ -1,10 +1,24 @@
|
|||||||
#ifndef COMMUNICATE_H
|
#ifndef COMMUNICATE_H
|
||||||
#define COMMUNICATE_H
|
#define COMMUNICATE_H
|
||||||
|
|
||||||
|
#include <Util.h>
|
||||||
|
|
||||||
|
struct FrameBuffer {
|
||||||
|
~FrameBuffer();
|
||||||
|
std::string fid;
|
||||||
|
std::string tid;
|
||||||
|
char* data{};
|
||||||
|
int len{};
|
||||||
|
};
|
||||||
|
|
||||||
class Communicate
|
class Communicate
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Communicate();
|
Communicate();
|
||||||
|
|
||||||
|
public:
|
||||||
|
static FrameBuffer* ParseBuffer(MutBuffer& buffer);
|
||||||
|
static bool PackBuffer(FrameBuffer* frame, char** buf, int& len);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // COMMUNICATE_H
|
#endif // COMMUNICATE_H
|
@ -13,5 +13,5 @@ main.cxx
|
|||||||
)
|
)
|
||||||
|
|
||||||
add_executable(RelayServer ${MSOURCES})
|
add_executable(RelayServer ${MSOURCES})
|
||||||
target_link_libraries(RelayServer PRIVATE wx::base wx::core Util)
|
target_link_libraries(RelayServer PRIVATE wx::base wx::core Util Protocol wx::net)
|
||||||
set_target_properties(RelayServer PROPERTIES WIN32_EXECUTABLE TRUE)
|
# set_target_properties(RelayServer PROPERTIES WIN32_EXECUTABLE TRUE)
|
@ -1,4 +1,6 @@
|
|||||||
#include "RelayServer.h"
|
#include "RelayServer.h"
|
||||||
|
#include <Communicate.h>
|
||||||
|
#include <InfoCommunicate.hpp>
|
||||||
|
|
||||||
RemoteServer::RemoteServer()
|
RemoteServer::RemoteServer()
|
||||||
{
|
{
|
||||||
@ -6,18 +8,121 @@ RemoteServer::RemoteServer()
|
|||||||
|
|
||||||
bool RemoteServer::Init(const wxString& ip, unsigned short port)
|
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()
|
int RemoteServer::Run()
|
||||||
{
|
{
|
||||||
return 0;
|
wxEventLoop loop;
|
||||||
|
return loop.Run();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteServer::OnServerEvent(wxSocketEvent& event)
|
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)
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,9 +14,12 @@
|
|||||||
#include <wx/socket.h>
|
#include <wx/socket.h>
|
||||||
#include <wx/wx.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>;
|
using highClock_t = std::chrono::time_point<std::chrono::high_resolution_clock>;
|
||||||
struct TranClient {
|
struct TranClient {
|
||||||
std::shared_ptr<wxSocketBase> wxSock;
|
std::shared_ptr<wxSocketBase> wxSock;
|
||||||
|
std::array<char, gBufferSize> buf;
|
||||||
MutBuffer buffer;
|
MutBuffer buffer;
|
||||||
int64_t onlineTime;
|
int64_t onlineTime;
|
||||||
highClock_t lastRecvTime;
|
highClock_t lastRecvTime;
|
||||||
@ -36,6 +39,7 @@ private:
|
|||||||
void thClientThread(const std::shared_ptr<wxSocketBase>& wxSock, const wxString& id);
|
void thClientThread(const std::shared_ptr<wxSocketBase>& wxSock, const wxString& id);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool thRun_{false};
|
||||||
wxWindowID serverId_;
|
wxWindowID serverId_;
|
||||||
std::shared_mutex clientsMutex_;
|
std::shared_mutex clientsMutex_;
|
||||||
std::unique_ptr<wxSocketServer> server_;
|
std::unique_ptr<wxSocketServer> server_;
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
#include "RelayServer.h"
|
#include "RelayServer.h"
|
||||||
|
|
||||||
class RelayServerApp : public wxApp
|
int main()
|
||||||
{
|
{
|
||||||
public:
|
wxInitializer initializer;
|
||||||
bool OnInit() override;
|
if (!initializer.IsOk()) {
|
||||||
};
|
fprintf(stderr, "Failed to initialize the wxWidgets library, aborting.");
|
||||||
|
return -1;
|
||||||
bool RelayServerApp::OnInit()
|
}
|
||||||
{
|
auto server_ = std::make_unique<RemoteServer>();
|
||||||
return true;
|
if (server_->Init("127.0.0.1", 8080)) {
|
||||||
}
|
server_->Run();
|
||||||
|
}
|
||||||
wxIMPLEMENT_APP(RelayServerApp);
|
return 0;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user