client:客户端进度更新。
This commit is contained in:
parent
0ed55b478d
commit
113fbee659
13
.vscode/settings.json
vendored
13
.vscode/settings.json
vendored
@ -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"
|
||||
}
|
||||
}
|
@ -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)
|
@ -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;
|
||||
}
|
||||
|
@ -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_;
|
||||
};
|
||||
|
@ -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 {
|
||||
|
@ -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));
|
||||
|
34
Information/InfoEnhance.hpp
Normal file
34
Information/InfoEnhance.hpp
Normal 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
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
Reference in New Issue
Block a user