commit 906e987d4b9a5d45e8ac10e07d800bd3578e495f Author: gxt_kt Date: Tue Nov 26 16:30:28 2024 +0800 first commit complete libhv tcp transfer diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4923a21 --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +*build* +bin/ +cmake-build* +.cache +.idea +.vscode +.cache +*__pycache__* +*.log diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..6be7ef8 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,40 @@ +cmake_minimum_required(VERSION 3.0) + +project(libhv) + +set(CMAKE_CXX_STANDARD 20) + +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + +# set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-elide-constructors") +# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-elide-constructors") + +if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux") + message("Building for Linux platform") +elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Darwin") + message("Building for macOS platform") + set(CMAKE_C_COMPILER "/opt/homebrew/bin/aarch64-apple-darwin23-gcc-14") # gcc clang` 指定c编译器 + set(CMAKE_CXX_COMPILER "/opt/homebrew/bin/aarch64-apple-darwin23-g++-14") # g++ clang++` 指定c++编译器 +elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Windows") + message("Building for Windows platform") +else() + message(FATAL_ERROR "Unsupported platform: ${CMAKE_SYSTEM_NAME}") +endif() + + +include_directories(include) +include_directories(/usr/local/include) + +find_package(debugstream) +# find_package(hv REQUIRED) + +set(LIB + debugstream + /usr/local/lib/libhv.so +) + +add_executable(client_tcp src/client_tcp_main.cc) +target_link_libraries(client_tcp ${LIB}) + +add_executable(server_tcp src/server_tcp_main.cc) +target_link_libraries(server_tcp ${LIB}) diff --git a/include/common.h b/include/common.h new file mode 100644 index 0000000..3f2ca53 --- /dev/null +++ b/include/common.h @@ -0,0 +1,8 @@ +#pragma once +#ifdef __linux__ +#include + +#elif __APPLE__ +#include "/Users/gxt_kt/Projects/debugstream/debugstream.hpp" +#elif _WIN32 +#endif diff --git a/include/libhv_client_tcp.hpp b/include/libhv_client_tcp.hpp new file mode 100644 index 0000000..9442eb2 --- /dev/null +++ b/include/libhv_client_tcp.hpp @@ -0,0 +1,98 @@ +#pragma once + +#include +#include +#include +#include + +#include "common.h" +#include "hv/TcpClient.h" +#include "hv/htime.h" + +class HvClient { + public: + void Log(const std::string &str) { + std::string log = gxt::format("[CLIENT](server{}:{}): ", ip_, port_); + std::cout << log << str << std::endl; + } + HvClient(const std::string &ip, int port, + std::function fun = {}) { + ip_ = ip; + port_ = port; + client_ = std::make_unique(); + int connfd = client_->createsocket(port, ip.c_str()); + if (connfd < 0) { + printf("create socket error"); + return; + } + + // 用来设置成功连接后执行的内容,例如一直打印心跳确保连接 + client_->onConnection = [&](const hv::SocketChannelPtr &channel) {}; + // client_->onConnection = [](const SocketChannelPtr &channel) { + // std::string peeraddr = channel->peeraddr(); + // if (channel->isConnected()) { + // printf("%s connected! connfd=%d\n", peeraddr.c_str(), channel->fd()); + // setInterval(3000, [channel](TimerID timerID) { + // if (channel->isConnected()) { + // char str[DATETIME_FMT_BUFLEN] = {0}; + // datetime_t dt = datetime_now(); + // datetime_fmt(&dt, str); + // channel->write(str); + // } else { + // killTimer(timerID); + // } + // }); + // } else { + // printf("%s disconnected! connfd=%d\n", peeraddr.c_str(), + // channel->fd()); + // } + // }; + + // client_->onMessage = [&](const SocketChannelPtr &channel, Buffer *buf) { + // OnMessage(channel, buf); + // }; + client_->onMessage = [&, fun](const hv::SocketChannelPtr &channel, + hv::Buffer *buf) { + if (fun) { + std::string msg((char *)buf->data()); + fun(msg); + } else { + OnMessage(channel, buf); + } + }; + + // 客户端写入完成时的内容 + client_->onWriteComplete = [&](const hv::SocketChannelPtr &channel, + hv::Buffer *buf) { + std::string_view msg((char *)buf->data()); + Log("onWriteComplete"); + }; + + reconn_setting_t reconn; + reconn_setting_init(&reconn); + reconn.min_delay = 1000; + reconn.max_delay = 10000; + reconn.delay_policy = 2; + client_->setReconnect(&reconn); + + // 设置加密通信 + // client_->withTLS(); + + client_->start(); + } + + void Send(const std::string &msg) { client_->send(msg); } + + void Stop() { client_->stop(); } + + ~HvClient() { client_->closesocket(); } + + private: + void OnMessage(const hv::SocketChannelPtr &channel, hv::Buffer *buf) { + std::string_view msg((char *)buf->data()); + } + + std::string ip_; + int port_; + std::unique_ptr client_; +}; diff --git a/include/libhv_server_tcp.hpp b/include/libhv_server_tcp.hpp new file mode 100644 index 0000000..d2b63fc --- /dev/null +++ b/include/libhv_server_tcp.hpp @@ -0,0 +1,77 @@ +#pragma once + +#include +#include +#include +#include + +#include "common.h" +#include "hv/TcpServer.h" +#include "hv/htime.h" + +class HvServer { + public: + void Log(const std::string &str) { + std::string log = gxt::format("[SERVER {}]: ", port_); + std::cout << log << str << std::endl; + } + HvServer(int port, std::function fun = {}) { + port_ = port; + server = std::make_unique(); + int listenfd = server->createsocket(port); + if (listenfd < 0) { + Log("createsocket error"); + return; + } + std::string logstr = "server listen on port " + std::to_string(port_) + + ", listenfd " + std::to_string(listenfd); + Log(logstr); + + server->onConnection = [&](const hv::SocketChannelPtr &channel) { + std::string peeraddr = channel->peeraddr(); + if (channel->isConnected()) { + char buffer[256] = {0}; + sprintf(buffer, "%s connected! connfd=%d\n", peeraddr.c_str(), + channel->fd()); + Log(std::string(buffer)); + } else { + char buffer[256] = {0}; + sprintf(buffer, "%s disconnected! connfd=%d\n", peeraddr.c_str(), + channel->fd()); + Log(std::string(buffer)); + } + }; + + // server->onMessage = [&](const hv::SocketChannelPtr &channel, + // hv::Buffer *buf) { OnMessage(channel, buf); }; + server->onMessage = [&, fun](const hv::SocketChannelPtr &channel, + hv::Buffer *buf) { + if (fun) { + std::string msg((char *)buf->data()); + fun(msg); + } else { + OnMessage(channel, buf); + } + }; + + server->setThreadNum(4); + server->start(); + Log("start server"); + } + + void Stop() { + if (server) { + server->stop(); + } + } + + private: + void OnMessage(const hv::SocketChannelPtr &channel, hv::Buffer *buf) { + std::string msg((char *)buf->data()); + Log(msg); + // server->broadcast(msg); // 用于广播回所有的连接客户端 + } + + int port_; + std::unique_ptr server; +}; diff --git a/src/client_tcp_main.cc b/src/client_tcp_main.cc new file mode 100644 index 0000000..b031e7f --- /dev/null +++ b/src/client_tcp_main.cc @@ -0,0 +1,33 @@ +#include +#include + +#include "common.h" +#include "libhv_client_tcp.hpp" +#include "libhv_server_tcp.hpp" + +using namespace std; + +int main(int argc, char *argv[]) { + // HvServer server(1234, [](std::string &str) { + // long rec = GetTimeUs(); + // long time = std::stol(str); + // gDebug() << "time diff:" << rec - time << "us"; + // // gDebug(str) << __PRETTY_FUNCTION__; + // }); + HvClient client("127.0.0.1", 1234, [](std::string &str) { + gDebug() << gxt::GetTimeUs(); + gDebug(str) << __PRETTY_FUNCTION__; + }); + + // gxt::Sleep(1); + // client.Send("send message"); + while (true) { + gxt::SleepMs(50); + std::string send_msg = gxt::format("{}", gxt::GetTimeUs()); + auto start = gxt::GetTimeUs(); + client.Send(send_msg); + auto end = gxt::GetTimeUs(); + gDebug(end - start); + gDebug() << G_SPLIT_LINE; + } +} diff --git a/src/server_tcp_main.cc b/src/server_tcp_main.cc new file mode 100644 index 0000000..42295ea --- /dev/null +++ b/src/server_tcp_main.cc @@ -0,0 +1,35 @@ +#include +#include + +#include "common.h" +#include "libhv_client_tcp.hpp" +#include "libhv_server_tcp.hpp" + +using namespace std; + +int main(int argc, char* argv[]) { + // HvServer server(1234, [](std::string &str) { + // long rec = GetTimeUs(); + // long time = std::stol(str); + // gDebug() << VAR(rec,time) << "time diff:" << rec - time << "us"; + // // gDebug(str) << __PRETTY_FUNCTION__; + // }); + HvServer server(1234, [](std::string& str) { gDebug(str.size()); }); + // HvClient client("127.0.0.1", 1234, [](std::string &str) { + // gDebug(str.size()); + // // gDebug() << GetTimeUs(); + // // gDebug(str) << __PRETTY_FUNCTION__; + // }); + + while (true); + // gxt::Sleep(1); + // client.Send("send message"); + // while (true) { + // gxt::Sleep(1); + // std::string send_msg = std::format("{}", GetTimeUs()); + // // gDebug(GetTimeUs()); + // client.Send(send_msg); + // + // gDebug() << G_SPLIT_LINE; + // } +}