client:客户端进度更新。

This commit is contained in:
taynpg 2025-05-10 21:43:25 +08:00
parent 0ed55b478d
commit 113fbee659
11 changed files with 177 additions and 46 deletions

13
.vscode/settings.json vendored
View File

@ -1,8 +1,8 @@
{
"files.autoSave": "onFocusChange",
"editor.fontSize": 14,
//"editor.fontFamily": "'Monaspace Krypton Light', 'Monaspace Krypton Light', 'Monaspace Krypton Light'",
"terminal.integrated.fontFamily": "monospace",
"editor.fontSize": 13,
"editor.fontFamily": "'Source Code Pro', 'Source Code Pro', 'Source Code Pro'",
"terminal.integrated.fontFamily": "Source Code Pro",
"cmake.configureOnOpen": true,
"cmake.debugConfig": {
"console": "integratedTerminal",
@ -122,6 +122,11 @@
"valarray": "cpp",
"charconv": "cpp",
"compare": "cpp",
"format": "cpp"
"format": "cpp",
"bit": "cpp",
"clocale": "cpp",
"concepts": "cpp",
"source_location": "cpp",
"stop_token": "cpp"
}
}

View File

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

View File

@ -1,4 +1,5 @@
#include "ClientCore.h"
#include <InfoEnhance.hpp>
ClientCore::ClientCore()
{
@ -12,14 +13,14 @@ bool ClientCore::Connect(const wxString& host, uint16_t port)
addr.Service(port);
socket_->SetEventHandler(*this, wxID_ANY);
socket_->SetNotify(wxSOCKET_CONNECTION_FLAG | wxSOCKET_INPUT_FLAG | wxSOCKET_LOST_FLAG);
socket_->SetNotify(wxSOCKET_INPUT | wxSOCKET_LOST_FLAG);
socket_->Notify(true);
socket_->SetFlags(wxSOCKET_BLOCK);
if (!socket_->Connect(addr)) {
return false;
}
return false;
return true;
}
void ClientCore::Disconnect()
@ -38,11 +39,28 @@ bool ClientCore::AskDirectory(const wxString& id, const wxString& path, DirFileI
void ClientCore::OnSocketEvent(wxSocketEvent& event)
{
auto* sock = event.GetSocket();
switch (event.GetSocketEvent()) {
case wxSOCKET_CONNECTION: {
wxLogMessage(_("Client connected."));
break;
}
case wxSOCKET_INPUT: {
sock->Read(buf_.data(), GBUFFER_SIZE);
auto size = sock->LastCount();
if (size > 0) {
buffer_.Push(buf_.data(), size);
while (thRun_) {
auto* frame = Communicate::ParseBuffer(buffer_);
if (!frame) {
break;
}
UseFrame(frame);
delete frame;
}
} else {
wxLogError(_("Read error: %s"), sock->LastError());
}
break;
}
case wxSOCKET_LOST: {
@ -52,3 +70,43 @@ void ClientCore::OnSocketEvent(wxSocketEvent& event)
break;
}
}
void ClientCore::UseFrame(FrameBuffer* buf)
{
std::stringstream ss;
switch (buf->dataType) {
case FRAME_TYPE_INFO_CLIENT: {
InfoClientVec vec;
ZeroCopyInput input(buf->dataMut, buf->len);
input.archive() >> vec;
break;
}
default:
break;
}
}
void ClientCore::HeartBeat()
{
}
bool ClientCore::Send(FrameBuffer* buf)
{
if (buf == nullptr) {
return false;
}
char* od = nullptr;
int odLen = 0;
if (!Communicate::PackBuffer(buf, &od, odLen)) {
return false;
}
socket_->Write(od, odLen);
if (socket_->Error()) {
delete[] od;
wxLogError(wxT("Send error: %s"), socket_->LastError());
return false;
}
delete[] od;
return true;
}

View File

@ -2,12 +2,17 @@
#define CLIENTCORE_H
#include <InfoClient.hpp>
#include <InfoCommunicate.hpp>
#include <InfoDirFile.hpp>
#include <Communicate.h>
#include <array>
#include <cstdint>
#include <memory>
#include <vector>
#include <wx/socket.h>
#include <Util.h>
class ClientCore : public wxEvtHandler
{
public:
@ -21,14 +26,33 @@ public:
bool GetOnlineList(InfoClientVec& infoClientVec);
bool AskDirectory(const wxString& id, const wxString& path, DirFileInfoVec& dirInfoVec);
private:
void UseFrame(FrameBuffer* buf);
private:
void OnSocketEvent(wxSocketEvent& event);
private:
void HeartBeat();
template <typename T> bool Send(const T& info)
{
std::stringstream ss;
cereal::BinaryOutputArchive archive(ss);
archive(info);
auto buf = std::make_shared<FrameBuffer>();
buf->dataConst = ss.view().data();
buf->len = ss.str().size();
return Send(wxSock, buf.get());
}
bool Send(FrameBuffer* buf);
private:
wxString id_;
bool thRun_;
MutBuffer buffer_;
std::array<char, GBUFFER_SIZE> buf_;
std::shared_ptr<wxSocketClient> socket_;
std::shared_ptr<wxThread> heartsThread_;
};

View File

@ -6,9 +6,12 @@
#include <cereal/types/vector.hpp>
#include <cstdint>
constexpr int GBUFFER_SIZE = 256;
enum MessageType {
MSG_TYPE_ASK_CLIENTS = 1,
MSG_TYPE_FORWORD_FAILED
MSG_TYPE_FORWORD_FAILED,
MSG_TYPE_HEARTBEAT,
};
struct InfoCommunicate {

View File

@ -17,25 +17,24 @@ enum FileType : uint32_t {
};
struct DirFileInfo {
std::string name;
uint64_t size = 0;
FileType type = None;
std::string fullPath;
std::string name;
uint64_t lastModifyTime = 0;
uint64_t size = 0;
uint16_t permission = 0;
uint64_t lastModifyTime = 0;
DirFileInfo() = default;
template <class Archive> void serialize(Archive& archive)
{
archive(CEREAL_NVP(type), CEREAL_NVP(fullPath), CEREAL_NVP(name), CEREAL_NVP(lastModifyTime), CEREAL_NVP(size),
CEREAL_NVP(permission));
archive(CEREAL_NVP(name), CEREAL_NVP(size), CEREAL_NVP(type), CEREAL_NVP(fullPath), CEREAL_NVP(permission),
CEREAL_NVP(lastModifyTime));
}
};
struct DirFileInfoVec {
std::vector<DirFileInfo> vec;
template <class Archive> void serialize(Archive& archive)
{
archive(CEREAL_NVP(vec));

View File

@ -0,0 +1,34 @@
#ifndef INFOENHANCE_HPP
#define INFOENHANCE_HPP
#include <cereal/archives/binary.hpp>
#include <cereal/types/memory.hpp>
#include <streambuf>
class ZeroCopyInput
{
public:
ZeroCopyInput(const char* data, size_t size) : streamBuf_(data, size), stream_(&streamBuf_)
{
}
cereal::BinaryInputArchive archive()
{
return cereal::BinaryInputArchive(stream_);
}
private:
class ConstStreamBuf : public std::streambuf
{
public:
ConstStreamBuf(const char* data, size_t size)
{
setg(const_cast<char*>(data), const_cast<char*>(data), const_cast<char*>(data + size));
}
};
ConstStreamBuf streamBuf_;
std::istream stream_;
};
#endif // INFOENHANCE_HPP

View File

@ -10,7 +10,7 @@ Communicate::Communicate()
/*
transm TCP
header 2 char: 0xFF 0xFE
unpack 1 char;
dataType 2 char;
from 32 char:
to 32 char:
len 4 char:
@ -27,26 +27,26 @@ FrameBuffer* Communicate::ParseBuffer(MutBuffer& buffer)
}
int 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) {
std::memcpy(&len, buffer.GetData() + find + sizeof(gHeader) + sizeof(uint16_t) + 64, sizeof(len));
if (buffer.Length() < (find + sizeof(gHeader) + sizeof(uint16_t) + 64 + len + sizeof(len) + sizeof(gTail)) || len < 0) {
return frame;
}
if (std::memcmp(buffer.GetData() + find + sizeof(gHeader) + sizeof(uint8_t) + 64 + sizeof(len) + len, gTail, sizeof(gTail)) !=
0) {
if (std::memcmp(buffer.GetData() + find + sizeof(gHeader) + sizeof(uint16_t) + 64 + sizeof(len) + len, gTail,
sizeof(gTail)) != 0) {
return frame;
}
frame = new FrameBuffer();
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);
frame->fid = std::string(buffer.GetData() + find + sizeof(gHeader) + sizeof(uint16_t), 32);
frame->tid = std::string(buffer.GetData() + find + sizeof(gHeader) + sizeof(uint16_t) + 32, 32);
if (len > 0) {
frame->dataMut = new char[len];
std::memcpy(frame->dataMut, buffer.GetData() + find + sizeof(gHeader) + sizeof(uint8_t) + 64 + sizeof(len), len);
std::memcpy(frame->dataMut, buffer.GetData() + find + sizeof(gHeader) + sizeof(uint16_t) + 64 + sizeof(len), len);
frame->len = len;
}
buffer.RemoveOf(0, find + sizeof(gHeader) + sizeof(uint8_t) + 64 + len + sizeof(len) + sizeof(gTail));
buffer.RemoveOf(0, find + sizeof(gHeader) + sizeof(uint16_t) + 64 + len + sizeof(len) + sizeof(gTail));
return frame;
}
@ -64,13 +64,13 @@ bool Communicate::PackBuffer(FrameBuffer* frame, char** buf, int& len)
} else {
dataPtr = frame->dataMut;
}
len = sizeof(gHeader) + sizeof(uint8_t) + 64 + sizeof(len) + frame->len + sizeof(gTail);
len = sizeof(gHeader) + sizeof(uint16_t) + 64 + sizeof(len) + frame->len + sizeof(gTail);
*buf = new char[len];
std::memcpy(*buf, gHeader, sizeof(gHeader));
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));
std::memcpy(*buf + sizeof(gHeader), &frame->dataType, sizeof(uint16_t));
std::memcpy(*buf + sizeof(gHeader) + sizeof(uint16_t), frame->fid.c_str(), 32);
std::memcpy(*buf + sizeof(gHeader) + sizeof(uint16_t) + 32, frame->tid.c_str(), 32);
std::memcpy(*buf + sizeof(gHeader) + sizeof(uint16_t) + 64, &frame->len, sizeof(len));
if (frame->len > 0) {
std::memcpy(*buf + sizeof(gHeader) + 64 + sizeof(len), dataPtr, frame->len);
}

View File

@ -4,15 +4,24 @@
#include <Util.h>
#include <cstdint>
enum FrameBufferType : uint16_t {
FRAME_TYPE_MSG_FILEDATA,
FRAME_TYPE_INFO_COMMUNICATE,
FRAME_TYPE_INFO_CLIENT,
FRAME_TYPE_INFO_DIRFILE,
FRAME_TYPE_MSG_YOURID
};
struct FrameBuffer {
FrameBuffer();
~FrameBuffer();
uint8_t unpack{};
int len{};
char* dataMut;
std::string fid;
std::string tid;
const char* dataConst;
char* dataMut;
int len{};
FrameBufferType dataType{};
};
class Communicate

View File

@ -29,7 +29,7 @@ bool RemoteServer::Init(const wxString& ip, unsigned short port)
// wxLogInfo(wxT("Server socket created on %s:%d"), addr.IPAddress(), addr.Service());
serverId_ = wxNewId();
server_->SetFlags(wxSOCKET_WAITALL);
//server_->SetFlags(wxSOCKET_NOWAIT);
server_->SetEventHandler(*this, serverId_);
server_->SetNotify(wxSOCKET_CONNECTION_FLAG | wxSOCKET_LOST_FLAG);
@ -100,9 +100,10 @@ void RemoteServer::thClientThread(const std::shared_ptr<wxSocketBase>& wxSock, c
client = clients_[id];
}
client->wxSock->SetFlags(wxSOCKET_BLOCK);
InfoCommunicate info;
while (thRun_) {
wxSock->Read(client->buf.data(), gBufferSize);
wxSock->Read(client->buf.data(), GBUFFER_SIZE);
auto br = wxSock->LastCount();
if (br == 0) {
wxLogMessage(wxT("Client disconnected: %s"), id);
@ -117,7 +118,7 @@ void RemoteServer::thClientThread(const std::shared_ptr<wxSocketBase>& wxSock, c
if (!frame) {
break;
}
if (frame->unpack != 0) {
if (frame->dataType != 0) {
std::stringstream ss;
ss.write(frame->dataMut, frame->len);
cereal::BinaryInputArchive inputArchive(ss);

View File

@ -17,8 +17,6 @@
#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>;
using sockPtr = std::shared_ptr<wxSocketBase>;
struct TranClient {
@ -27,7 +25,7 @@ struct TranClient {
int64_t onlineTime;
std::string name;
highClock_t lastRecvTime;
std::array<char, gBufferSize> buf;
std::array<char, GBUFFER_SIZE> buf;
};
class RemoteServer : public wxEvtHandler