From fc96f48ee046c5116a85db0f601b37e53b14338a Mon Sep 17 00:00:00 2001 From: taynpg Date: Wed, 11 Dec 2024 22:51:43 +0800 Subject: [PATCH] =?UTF-8?q?run=EF=BC=9A=E5=88=9D=E6=AD=A5=E8=B0=83?= =?UTF-8?q?=E8=AF=95=E9=80=9A=E8=AE=AF=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/settings.json | 15 ++++++++++++-- CMakeLists.txt | 6 ++++-- net/net_base.cpp | 35 +++++++++++++++++++++----------- net/net_base.h | 15 ++++++++++---- ofen | 2 +- test.cpp | 16 --------------- test1.cpp | 38 ++++++++++++++++++++++++++++++++++ test2.cpp | 35 ++++++++++++++++++++++++++++++++ util/CMakeLists.txt | 6 ++---- util/util.cpp | 47 ++++++++++++++++++++++++++++++++++++++----- util/util.h | 14 ++++++++----- 11 files changed, 178 insertions(+), 51 deletions(-) delete mode 100644 test.cpp create mode 100644 test1.cpp create mode 100644 test2.cpp diff --git a/.vscode/settings.json b/.vscode/settings.json index 98a3287..b7cf94a 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -20,7 +20,7 @@ ] }, "cmake.configureSettings": { - "CMAKE_TOOLCHAIN_FILE": "${env:VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake" + //"CMAKE_TOOLCHAIN_FILE": "${env:VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake" }, "cmake.options.statusBarVisibility": "visible", "cmake.generator": "Ninja", @@ -110,6 +110,17 @@ "xstddef": "cpp", "xtr1common": "cpp", "xtree": "cpp", - "xutility": "cpp" + "xutility": "cpp", + "bit": "cpp", + "compare": "cpp", + "concepts": "cpp", + "coroutine": "cpp", + "expected": "cpp", + "format": "cpp", + "forward_list": "cpp", + "source_location": "cpp", + "span": "cpp", + "stop_token": "cpp", + "*.ipp": "cpp" } } \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index ff0af29..0446fa8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,5 +19,7 @@ add_subdirectory(util) add_subdirectory(server) add_subdirectory(client) -add_executable(transm_test test.cpp) -target_link_libraries(transm_test PRIVATE trans_net trans_util) \ No newline at end of file +add_executable(transm_test1 test1.cpp) +target_link_libraries(transm_test1 PRIVATE trans_net trans_util) +add_executable(transm_test2 test2.cpp) +target_link_libraries(transm_test2 PRIVATE trans_net trans_util) \ No newline at end of file diff --git a/net/net_base.cpp b/net/net_base.cpp index 7d0c9ce..e5ab068 100644 --- a/net/net_base.cpp +++ b/net/net_base.cpp @@ -8,7 +8,8 @@ CServer::~CServer() { } -CClient::CClient(const std::shared_ptr& logger) : logger_(logger), io_context_(), socket_(io_context_) +CClient::CClient(asio::io_context& io_context, const std::shared_ptr& logger) + : logger_(logger), io_context_(io_context), socket_(io_context_) { } @@ -54,16 +55,26 @@ bool CClient::Send(const char* data, int len) } } -std::string CClient::Receive() +void CClient::register_func(ExFun_t& f) { - try { - std::vector buffer(1024); - size_t length = socket_.read_some(asio::buffer(buffer)); - std::string received_data(buffer.data(), length); - logger_->info("Received data len: {}", length); - return received_data; - } catch (const std::exception& ex) { - logger_->error("Receive failed: {}", ex.what()); - return ""; - } + fun_ = f; +} + +void CClient::Receive() +{ + auto self(shared_from_this()); + socket_.async_read_some(asio::buffer(tmp_buf_), [this, self](std::error_code ec, std::size_t length) { + if (!ec) { + std::lock_guard lock(mutex_); + buffer_.push(tmp_buf_.data(), length); + auto* frame = CTransProtocal::parse(buffer_); + if (frame) { + if (fun_) { + fun_(frame); + } + delete frame; + } + Receive(); + } + }); } diff --git a/net/net_base.h b/net/net_base.h index e86a549..c9e5142 100644 --- a/net/net_base.h +++ b/net/net_base.h @@ -3,8 +3,11 @@ #include "util.h" #include #include +#include +#include using namespace ofen; +using ExFun_t = std::function; class CServer { public: @@ -12,20 +15,24 @@ public: ~CServer(); }; -class CClient +class CClient : public std::enable_shared_from_this { public: - CClient(const std::shared_ptr& logger); + CClient(asio::io_context& io_context, const std::shared_ptr& logger); ~CClient(); public: bool Connect(const std::string& host, const std::string& port); void Disconnect(); bool Send(const char* data, int len); - std::string Receive(); + void register_func(ExFun_t& f); + void Receive(); private: std::shared_ptr logger_; - asio::io_context io_context_; + asio::io_context& io_context_; asio::ip::tcp::socket socket_; + std::mutex mutex_; CMutBuffer buffer_; + std::array tmp_buf_; + ExFun_t fun_; }; \ No newline at end of file diff --git a/ofen b/ofen index 79e086b..0f7a8d3 160000 --- a/ofen +++ b/ofen @@ -1 +1 @@ -Subproject commit 79e086bae5509753eff4dce5669b3a7f5eac525f +Subproject commit 0f7a8d3c928ef93c6250fa048b5c1cda2e42ed57 diff --git a/test.cpp b/test.cpp deleted file mode 100644 index 841d4c4..0000000 --- a/test.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#include "util.h" -#include -#include - -int main() -{ - char testBuffer[] = "NIhao"; - auto logger = get_logger("test", "test.log"); - CClient client(logger); - if (client.Connect("127.0.0.1", "8989")) { - std::cout << client.Send(testBuffer, sizeof(testBuffer)) << std::endl; - client.Receive(); - } - client.Disconnect(); - return 0; -} \ No newline at end of file diff --git a/test1.cpp b/test1.cpp new file mode 100644 index 0000000..5ea9342 --- /dev/null +++ b/test1.cpp @@ -0,0 +1,38 @@ +#include "util.h" +#include +#include + +int main() +{ + CFrameBuffer* buf = new CFrameBuffer(); + buf->data_ = new char[256]; + std::memset(buf->data_, 0x0, 256); + int buf_len = std::snprintf(buf->data_, 256, "%s", "Hello Cplusplus."); + buf->len_ = buf_len; + char* data = nullptr; + int len = 0; + if (!CTransProtocal::pack(buf, &data, len)) { + delete buf; + return -1; + } + auto logger = get_logger("test1", "test1.log"); + asio::io_context io_context; + CClient client(io_context, logger); + if (!client.Connect("127.0.0.1", "8080")) { + return -1; + } + logger->info("send len:{}", len); + std::cout << client.Send(data, len) << std::endl; + std::thread t([&io_context]() { io_context.run(); }); + char line[512]{}; + while (std::cin.getline(line, 512)) { + if (std::strstr(line, "end")) { + break; + } + } + client.Disconnect(); + t.join(); + + delete buf; + return 0; +} \ No newline at end of file diff --git a/test2.cpp b/test2.cpp new file mode 100644 index 0000000..fe4c0c1 --- /dev/null +++ b/test2.cpp @@ -0,0 +1,35 @@ +#include +#include + +std::shared_ptr g_Logger; + +void TestHandle(CFrameBuffer* buf) +{ + g_Logger->info("type: {}", buf->type_); + g_Logger->info("len: {}", buf->len_); +} + +int main() +{ + char buffer[] = "Java"; + g_Logger = get_logger("test1", "test1.log"); + asio::io_context io_context; + std::shared_ptr client = std::make_shared(io_context, g_Logger); + if (!client->Connect("127.0.0.1", "8080")) { + return -1; + } + client->Send(buffer, sizeof(buffer)); + std::function func = TestHandle; + client->register_func(func); + client->Receive(); + std::thread t([&io_context]() { io_context.run(); }); + char line[512]{}; + while (std::cin.getline(line, 512)) { + if (std::strstr(line, "end")) { + break; + } + } + client->Disconnect(); + t.join(); + return 0; +} \ No newline at end of file diff --git a/util/CMakeLists.txt b/util/CMakeLists.txt index a3b5043..945d23b 100644 --- a/util/CMakeLists.txt +++ b/util/CMakeLists.txt @@ -1,15 +1,13 @@ cmake_minimum_required(VERSION 3.16) project(trans_util LANGUAGES CXX) +set(CMAKE_CXX_STANDARD 17) if (MSVC) - add_definitions(-D_WIN32_WINNT=0x0601) add_compile_options(/source-charset:utf-8) endif() -set(SOURCES - util.h util.cpp -) +set(SOURCES util.h util.cpp) add_library(trans_util STATIC ${SOURCES}) target_link_libraries(trans_util PUBLIC Ofen) target_include_directories(trans_util PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) \ No newline at end of file diff --git a/util/util.cpp b/util/util.cpp index c6daf5e..c310555 100644 --- a/util/util.cpp +++ b/util/util.cpp @@ -1,4 +1,6 @@ #include "util.h" +#include +#include std::shared_ptr get_logger(const std::string& mark, const std::string& log_file) { @@ -32,21 +34,56 @@ CTransProtocal::~CTransProtocal() CFrameBuffer* CTransProtocal::parse(CMutBuffer& buffer) { CFrameBuffer* result = nullptr; - char header[] = {0xFF, 0xFE}; - char tail[] = {0xFF, 0xFF}; + unsigned char header[] = {0xFF, 0xFE}; + unsigned char tail[] = {0xFF, 0xFF}; - int find = buffer.index_of(header, sizeof(header)); + int find = buffer.index_of((const char*)header, sizeof(header)); if (find < 0) { return result; } - short int type = *(reinterpret_cast(buffer.get_data() + find)); + int16_t type = *(reinterpret_cast(buffer.get_data() + find + 2)); + int32_t len = *(reinterpret_cast(buffer.get_data() + find + 2 + sizeof(int16_t))); + int32_t tail_index = find + 2 + sizeof(int16_t) + sizeof(int32_t) + len; + if (buffer.get_len() - 2 < tail_index || len < 0) { + return result; + } + unsigned char taila = *((unsigned char*)(buffer.get_data() + tail_index)); + unsigned char tailb = *((unsigned char*)(buffer.get_data() + tail_index + 1)); + if (taila != tail[0] || tailb != tail[1]) { + return result; + } + result = new CFrameBuffer(); + result->data_ = new char[len]; + result->len_ = len; + std::memset(result->data_, 0x0, len); + std::memcpy(result->data_, buffer.get_data() + find + 2 + sizeof(int16_t) + sizeof(int32_t), len); + buffer.remove_of(0, tail_index + 2); return result; } +bool CTransProtocal::pack(CFrameBuffer* buf, char** out_buf, int& len) +{ + if (buf == nullptr || buf->data_ == nullptr || buf->len_ < 1) { + return false; + } + unsigned char header[] = {0xFF, 0xFE}; + unsigned char tail[] = {0xFF, 0xFF}; + len = buf->len_ + 10; + *out_buf = new char[len]; + std::memcpy(*out_buf, header, 2); + std::memcpy(*out_buf + 2, &buf->type_, 2); + std::memcpy(*out_buf + 4, &buf->len_, 4); + std::memcpy(*out_buf + 8, buf->data_, buf->len_); + std::memcpy(*out_buf + len - 2, tail, 2); + return true; +} + CFrameBuffer::CFrameBuffer() { } CFrameBuffer::~CFrameBuffer() { -} + delete[] data_; + len_ = 0; +} \ No newline at end of file diff --git a/util/util.h b/util/util.h index 0522134..ac97876 100644 --- a/util/util.h +++ b/util/util.h @@ -1,9 +1,9 @@ -#ifndef TRANSM_UTIL -#define TRANSM_UTIL +#pragma once #include #include #include #include "of_util.h" +#include using namespace ofen; std::shared_ptr get_logger(const std::string& mark, const std::string& log_file); @@ -12,6 +12,10 @@ class CFrameBuffer public: CFrameBuffer(); ~CFrameBuffer(); +public: + int16_t type_{}; + char* data_{}; + int len_{}; }; /* @@ -28,6 +32,6 @@ public: CTransProtocal(); ~CTransProtocal(); public: - CFrameBuffer* parse(CMutBuffer& buffer); -}; -#endif \ No newline at end of file + static CFrameBuffer* parse(CMutBuffer& buffer); + static bool pack(CFrameBuffer* buf, char** out_buf, int& len); +}; \ No newline at end of file