From e53dc4a080cafa3595af5f52a1c340437c191b2c Mon Sep 17 00:00:00 2001 From: Sherlock <1297399478@qq.com> Date: Mon, 16 Jun 2025 08:52:40 +0800 Subject: [PATCH] MyLib --- .gitignore | 2 + CMakeLists.txt | 33 ++++ Log/ConfigParser.cpp | 70 +++++++++ Log/ConfigParser.h | 29 ++++ Log/LogL.cpp | 331 ++++++++++++++++++++++++++++++++++++++++ Log/LogL.h | 98 ++++++++++++ Serial/SerialPort.cpp | 249 ++++++++++++++++++++++++++++++ Serial/SerialPort.h | 64 ++++++++ Socket/NetworkRelated.h | 51 +++++++ Socket/TCP.cpp | 156 +++++++++++++++++++ Socket/TCP.h | 79 ++++++++++ Socket/UDP.cpp | 207 +++++++++++++++++++++++++ Socket/UDP.h | 95 ++++++++++++ Test/LogTest.cpp | 47 ++++++ Test/ParserTest.cpp | 19 +++ Test/SerialTest.cpp | 59 +++++++ Test/TcpTest.cpp | 55 +++++++ Test/Test.h | 16 ++ Test/UdpTest.cpp | 29 ++++ Thread/ThreadL.cpp | 3 + Thread/ThreadL.h | 6 + config.ini | 8 + main.cpp | 19 +++ 23 files changed, 1725 insertions(+) create mode 100644 .gitignore create mode 100644 CMakeLists.txt create mode 100644 Log/ConfigParser.cpp create mode 100644 Log/ConfigParser.h create mode 100644 Log/LogL.cpp create mode 100644 Log/LogL.h create mode 100644 Serial/SerialPort.cpp create mode 100644 Serial/SerialPort.h create mode 100644 Socket/NetworkRelated.h create mode 100644 Socket/TCP.cpp create mode 100644 Socket/TCP.h create mode 100644 Socket/UDP.cpp create mode 100644 Socket/UDP.h create mode 100644 Test/LogTest.cpp create mode 100644 Test/ParserTest.cpp create mode 100644 Test/SerialTest.cpp create mode 100644 Test/TcpTest.cpp create mode 100644 Test/Test.h create mode 100644 Test/UdpTest.cpp create mode 100644 Thread/ThreadL.cpp create mode 100644 Thread/ThreadL.h create mode 100644 config.ini create mode 100644 main.cpp diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c89c799 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.idea/ +build_C/ diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..19e79bb --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,33 @@ +cmake_minimum_required(VERSION 3.28) +project(lxzl) + +set(CMAKE_CXX_STANDARD 11) + +include_directories(Log) +aux_source_directory(Log LOG_LIST) +include_directories(Serial) +aux_source_directory(Serial SERIAL_LIST) +include_directories(Socket) +aux_source_directory(Socket SOCKET_LIST) +include_directories(Thread) +aux_source_directory(Thread THREAD_LIST) +include_directories(Test) +aux_source_directory(Test TEST_LIST) + +add_executable(${PROJECT_NAME} main.cpp ${LOG_LIST} ${SERIAL_LIST} ${SOCKET_LIST} ${THREAD_LIST} ${TEST_LIST}) + +if (CMAKE_SYSTEM_NAME STREQUAL "Windows") + target_link_libraries(${PROJECT_NAME} ws2_32) +else () + target_link_libraries(${PROJECT_NAME} pthread) +endif () + +#设置配置文件 +set(DIST_FILES config.ini) +# 把配置文件复制到构建目录 +foreach (file ${DIST_FILES}) + # 使用 RELATIVE 配置,这样路径是相对于 CMakeLists.txt 的 + set(src_path "${file}") + set(dst_path "${CMAKE_CURRENT_BINARY_DIR}/${file}") + configure_file(${src_path} ${dst_path} COPYONLY) +endforeach () \ No newline at end of file diff --git a/Log/ConfigParser.cpp b/Log/ConfigParser.cpp new file mode 100644 index 0000000..e30953e --- /dev/null +++ b/Log/ConfigParser.cpp @@ -0,0 +1,70 @@ +#include "ConfigParser.h" + +#include +#include +#include +#include + +using namespace std; + +/** 清理字符串前后空格 */ +void trim(std::string &s) { + auto wsfront = std::find_if_not(s.begin(), s.end(), [](int c) { + return std::isspace(c); + }); + auto wsback = std::find_if_not(s.rbegin(), s.rend(), [](int c) { + return std::isspace(c); + }).base(); + s = (wsback <= wsfront) ? std::string() : std::string(wsfront, wsback); +} + +CPStatus configFromIni(const std::string &path, std::unordered_map &config) { + CPStatus result = CPSUCCESS; + //打开文件 + ifstream file(path); + if (!file.is_open()) { + result = CPFILE; + return result; + } + // 一次性读取整个文件(减少I/O操作) + file.seekg(0, std::ios::end); + size_t size = file.tellg(); + file.seekg(0, std::ios::beg); + string m_buffer; + m_buffer.resize(size); + file.read(&m_buffer[0], static_cast(size)); + //处理全部数据 + config.clear(); + std::string line; + line.reserve(256); // 预分配行缓存 + for (auto it = m_buffer.cbegin(); it != m_buffer.cend();) { + // 快速跳过空白行 + while (it != m_buffer.cend() && (*it == '\r' || *it == '\n')) { ++it; } + if (it == m_buffer.cend()) break; + + // 获取行内容 + line.clear(); + while (it != m_buffer.cend() && *it != '\r' && *it != '\n' && *it != '\0') { + line += *it++; + } + //处理行内容 + // 跳过空行和注释 + if (line.empty() || line[0] == ';' || line[0] == '#') { + ++it; + continue; + } + + // 分割键值对 + size_t eq_pos = line.find('='); + if (eq_pos != std::string::npos) { + std::string key = line.substr(0, eq_pos); + std::string value = line.substr(eq_pos + 1); + trim(key); + trim(value); + if (!key.empty()) { + config[key] = value; // 移动语义自动优化 + } + } + } + return result; +} diff --git a/Log/ConfigParser.h b/Log/ConfigParser.h new file mode 100644 index 0000000..bcaed92 --- /dev/null +++ b/Log/ConfigParser.h @@ -0,0 +1,29 @@ +#ifndef CONFIGPARSER_H +#define CONFIGPARSER_H +/** + * 配置文件解析模块 + * 目标:实现对多种文件格式的解析功能 + * 1、ini格式文件 √ + * 2、json格式文件 未实现 + * 3、YAML格式文件 未实现 + * 4、Protobuf格式文件 未实现 + */ +#include +#include + +/** 状态码 */ +enum CPStatus { + CPSUCCESS = 0,//成功 + CPFILE = -1//文件错误 +}; + +/** + * 读取ini类型的配置文件 + * @param path 配置文件路径 + * @param config 存储配置文件的unordered_map容器 + * @return 状态码 + */ +CPStatus configFromIni(const std::string &path, std::unordered_map &config); + + +#endif //CONFIGPARSER_H diff --git a/Log/LogL.cpp b/Log/LogL.cpp new file mode 100644 index 0000000..abaa719 --- /dev/null +++ b/Log/LogL.cpp @@ -0,0 +1,331 @@ +#include "LogL.h" + +#include +#include +#include +#include +#include +#include + +#ifdef __linux__ +#include +#endif + +using namespace std; + +LogL::LogL(LogType logType, bool isSync, std::string logPath) : m_isSync(isSync), m_logType(logType), + m_logPath(std::move(logPath)), m_file(nullptr), + m_thread(nullptr), m_sender(nullptr) { + switch (m_logType) { + case LTStd: { + break; + } + case LTTxt: { + //创建文件 + myDateTime now; + std::string dirName; + if (m_logPath.empty()) { + dirName = "logs"; + } + else { + dirName = m_logPath; + } + myMkdir(dirName.c_str()); + std::string fileName = dirName + "/" + now.toDate() + ".txt"; + m_file = new std::ofstream(fileName, std::ios::app); + m_today = now.day; + break; + } + case LTUdp: { + m_sender = new UDPSender; + std::vector parts; + std::stringstream ss(m_logPath); + std::string part; + // 按逗号分割字符串 + while (std::getline(ss, part, ',')) { + parts.push_back(part); + } + if (parts.size() == 3) { + m_sender->set_destination(parts[0], stoi(parts[1])); + m_sender->set_source(parts[0], stoi(parts[2])); + } + else if (parts.size() == 2) { + m_sender->set_destination(parts[0], stoi(parts[1])); + } + else { + throw std::runtime_error("UDP Path Error"); + } + break; + } + case LTTcp: { + + break; + } + } + if (!m_isSync) { + //运行日志线程 + m_thread_run = true; + m_thread = new std::thread(&LogL::logThread, this); + } +} + +LogL::~LogL() { + //停止线程 + while (m_thread) { + if (m_log_queue.empty()) { + cout << "已清空日志队列" << endl; + break; + } + cout << "正在写入剩余日志:" << m_log_queue.size() << endl; + this_thread::sleep_for(chrono::milliseconds(300)); + } + if (m_thread) { + //设置结束并等待线程结束 + m_thread_run = false; + m_cond_empty.notify_all(); + if (m_thread->joinable()) { + m_thread->join(); + } + delete m_thread; + m_thread = nullptr; + } + //关闭文件 + m_mtx.lock(); + if (m_file) { + m_file->flush(); + m_file->close(); + delete m_file; + m_file = nullptr; + } + m_mtx.unlock(); + cout << "日志析构函数完成" << endl; +} + +void LogL::logThread() { + std::string str; + while (m_thread_run) { + //如果队列为空,等待 + if (m_log_queue.empty()) { + std::unique_lock lock(m_mtx); + m_cond_empty.wait(lock); + continue; + } + //取出队列头并出栈 + str = m_log_queue.front(); + m_log_queue.pop(); + m_cond_full.notify_one(); + switch (m_logType) { + case LTStd: + cout << str << endl; + break; + case LTTxt: { + if (m_file == nullptr) { + std::cerr << "logThread():日志文件打开失败" << endl; + break; + } + *m_file << str << endl; + break; + } + case LTUdp: + try { + m_sender->send(str); + } + catch (const std::runtime_error &e) { + std::cerr << e.what() << endl; + } + break; + case LTTcp: + break; + } + + } +} + +void LogL::debug(const std::string &str) { + log(str, LLDebug); +} + +void LogL::info(const std::string &str) { + log(str, LLInfo); +} + +void LogL::warn(const std::string &str) { + log(str, LLWarn); +} + +void LogL::error(const std::string &str) { + log(str, LLError); +} + +void LogL::log(const std::string &str, LogLevel level) { + string tmpLever; + switch (level) { + case LLDebug: + tmpLever = " [debug]:"; + break; + case LLInfo: + tmpLever = " [info]:"; + break; + case LLWarn: + tmpLever = " [warn]:"; + break; + case LLError: + tmpLever = " [error]:"; + break; + } + myDateTime now; + if (m_logType == LTTxt) { + //逾期更新日志文件 + m_mtx.lock(); + if (now.day != m_today) { + if (m_file) { + m_file->flush(); + m_file->close(); + delete m_file; + m_file = nullptr; + } + std::string dirName; + if (m_logPath.empty()) { + dirName = "log"; + } + else { + dirName = m_logPath; + } + myMkdir(dirName.c_str()); + std::string fileName = + dirName + "/" + now.toDate() + ".txt"; + m_file = new std::ofstream(fileName, std::ios::app); + } + m_mtx.unlock(); + } + std::string logInfo = now.toDateTime() + tmpLever + str; + if (m_isSync) { + switch (m_logType) { + case LTStd: + cout << logInfo << endl; + break; + case LTTxt: { + if (m_file == nullptr) { + std::cerr << "日志文件打开失败" << endl; + break; + } + *m_file << logInfo << endl; + break; + } + case LTUdp: + try { + m_sender->send(logInfo); + } + catch (const std::runtime_error &e) { + std::cerr << e.what() << endl; + } + break; + case LTTcp: + break; + } + } + else { + if (m_log_queue.size() >= 4096) { + std::unique_lock lock(m_mtx); + m_cond_full.wait(lock); + } + m_mtx.lock(); + m_log_queue.push(logInfo); + m_mtx.unlock(); + m_cond_empty.notify_all(); + } +} + + +bool createPath(const char *path) { + struct stat st = {0}; + if (stat(path, &st) == -1) { +#if WIN32 + if (mkdir(path) == 0) { +#else + if (mkdir(path,0777) == 0) { +#endif + return true; + } + else { + std::cerr << "Failed to create directory: " << path << std::endl; + return false; + } + } + return true; // Directory already exists +} + +bool myMkdir(const char *path) { + char buffer[1024]; + char *p = buffer; + const char *sep = "/"; + + strcpy(buffer, path); + while ((p = strchr(p, *sep)) != nullptr) { + *p = '\0'; + if (!createPath(buffer)) { + return false; + } + *p = *sep; + p++; + } + createPath(buffer); + return true; +} + +myDateTime::myDateTime() { + auto now = std::chrono::system_clock::now(); + std::time_t time1 = std::chrono::system_clock::to_time_t(now); + std::tm *tm1 = std::localtime(&time1); + year = tm1->tm_year + 1900; + month = tm1->tm_mon + 1; + day = tm1->tm_mday; + hour = tm1->tm_hour; + minute = tm1->tm_min; + second = tm1->tm_sec; +} + +std::string myDateTime::toDate() const { + string date = to_string(year) + "-"; + if (month < 10) { + date += "0" + to_string(month) + "-"; + } + else { + date += to_string(month) + "-"; + } + if (day < 10) { + date += "0" + to_string(day); + } + else { + date += to_string(day); + } + return date; +} + +std::string myDateTime::toTime() const { + string time; + if (hour < 10) { + time += "0" + to_string(hour) + ":"; + } + else { + time += to_string(hour) + ":"; + } + if (minute < 10) { + time += "0" + to_string(minute) + ":"; + } + else { + time += to_string(minute) + ":"; + } + if (second < 10) { + time += "0" + to_string(second); + } + else { + time += to_string(second); + } + return time; +} + +std::string myDateTime::toDateTime() const { + string dateTime = toDate() + " " + toTime(); + return dateTime; +} diff --git a/Log/LogL.h b/Log/LogL.h new file mode 100644 index 0000000..5bbe685 --- /dev/null +++ b/Log/LogL.h @@ -0,0 +1,98 @@ +#ifndef LXZL_LOGL_H +#define LXZL_LOGL_H +/** + * 日志生成模块 + * 目标:支持同步、异步两种方式;支持多种输出方式(控制台、文件、udp、tcp) + */ +#include "UDP.h" + +#include +#include +#include +#include +#include + +enum LogType{ + LTStd,//日志输出到控制台 + LTTxt,//日志输出到文本文件 + LTUdp,//日志输出到UDP + LTTcp,//日志输出到TCP +}; +enum LogLevel{ + LLDebug,//调试 + LLInfo,//一般 + LLWarn,//警告 + LLError,//错误 +}; + + +class LogL { +public: + /** + * 日志构造函数 + * @param logType 日志输出类型 + * @param isSync true:同步/false:异步 + * @param logPath 输出地址(LTStd:无;LTTxt:填写路径;LTUdp:填写ip端口) + */ + explicit LogL(LogType logType, bool isSync = true, std::string logPath = ""); + ~LogL(); + + /** + * 调试日志 + * @param str 日志内容 + */ + void debug(const std::string &str); + void info(const std::string &str); + void warn(const std::string &str); + void error(const std::string &str); + +private: + + void logThread(); + + void log(const std::string &str, LogLevel level); + + +private: + std::thread *m_thread; + bool m_thread_run; + bool m_isSync;//是否同步 + LogType m_logType;//输出类型 + std::string m_logPath;//输出地址 + std::queue m_log_queue;//日志容器 + std::mutex m_mtx; + std::condition_variable m_cond_empty;//空时停止 + std::condition_variable m_cond_full;//满时停止 + std::ofstream *m_file; + int32_t m_today; + UDPSender *m_sender; +}; + + +/** + * 创建目录 + * @param path 路径 + * @return bool是否创建成功 + */ +bool myMkdir(const char *path); + +/** + * 获取当前日期时间 + */ +class myDateTime { +public: + myDateTime(); + + int32_t year; + int32_t month; + int32_t day; + int32_t hour; + int32_t minute; + int32_t second; + + std::string toDate() const; + std::string toTime() const; + std::string toDateTime() const; +}; + +#endif //LXZL_LOGL_H diff --git a/Serial/SerialPort.cpp b/Serial/SerialPort.cpp new file mode 100644 index 0000000..e0b4853 --- /dev/null +++ b/Serial/SerialPort.cpp @@ -0,0 +1,249 @@ +#include "SerialPort.h" + +#include +#include + +SerialPort::SerialPort(const std::string &device, int baudrate) : running_(false) { +#ifdef _WIN32 + fd_ = CreateFile(device.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (fd_ == INVALID_HANDLE_VALUE) { + throw std::system_error(GetLastError(), std::system_category(), "Failed to open serial port"); + } + + DCB dcbSerialParams = {0}; + dcbSerialParams.DCBlength = sizeof(dcbSerialParams); + if (!GetCommState(fd_, &dcbSerialParams)) { + CloseHandle(fd_); + throw std::system_error(GetLastError(), std::system_category(), "GetCommState failed"); + } + + dcbSerialParams.BaudRate = baudrate; + dcbSerialParams.ByteSize = 8; + dcbSerialParams.Parity = NOPARITY; + dcbSerialParams.StopBits = ONESTOPBIT; + dcbSerialParams.fOutxCtsFlow = FALSE; + dcbSerialParams.fOutxDsrFlow = FALSE; + dcbSerialParams.fDtrControl = DTR_CONTROL_ENABLE; + dcbSerialParams.fRtsControl = RTS_CONTROL_ENABLE; + + if (!SetCommState(fd_, &dcbSerialParams)) { + CloseHandle(fd_); + throw std::system_error(GetLastError(), std::system_category(), "SetCommState failed"); + } + + COMMTIMEOUTS timeouts = {0}; + timeouts.ReadIntervalTimeout = 50; + timeouts.ReadTotalTimeoutConstant = 50; + timeouts.ReadTotalTimeoutMultiplier = 10; + timeouts.WriteTotalTimeoutConstant = 50; + timeouts.WriteTotalTimeoutMultiplier = 10; + if (!SetCommTimeouts(fd_, &timeouts)) { + CloseHandle(fd_); + throw std::system_error(GetLastError(), std::system_category(), "SetCommTimeouts failed"); + } +#else + fd_ = open(device.c_str(), O_RDWR | O_NOCTTY | O_NDELAY); + if (fd_ < 0) { + throw std::system_error(errno, std::generic_category(), "Failed to open serial port"); + } + configure(baudrate, fd_); +#endif +} + +SerialPort::~SerialPort() { + stop_receiving(); + close(); +} + +void SerialPort::configure(int baudrate, int fd) { +#ifdef _WIN32 + // Windows配置在构造函数中已完成 +#else + termios tty{}; + if (tcgetattr(fd, &tty) != 0) { + throw std::system_error(errno, std::generic_category(), "tcgetattr failed"); + } + + speed_t speed = getBaudRate(baudrate); + cfsetispeed(&tty, speed); + cfsetospeed(&tty, speed); + + tty.c_cflag &= ~PARENB; + tty.c_cflag &= ~CSTOPB; + tty.c_cflag &= ~CSIZE; + tty.c_cflag |= CS8; + tty.c_cflag &= ~CRTSCTS; + tty.c_cflag |= CREAD | CLOCAL; + + tty.c_lflag &= ~(ICANON | ECHO | ECHOE | IEXTEN | ISIG); + tty.c_iflag &= ~(ICRNL | INLCR | IGNCR); + tty.c_iflag |= IGNBRK; + + tty.c_oflag &= ~OPOST; + + tty.c_cc[VMIN] = 1; + tty.c_cc[VTIME] = 0; + + if (tcsetattr(fd, TCSANOW, &tty) != 0) { + throw std::system_error(errno, std::generic_category(), "tcsetattr failed"); + } + + int flags = fcntl(fd, F_GETFL, 0); + fcntl(fd, F_SETFL, flags & ~O_NONBLOCK); +#endif +} + +ssize_t SerialPort::write(const std::vector &data) { +#ifdef _WIN32 + DWORD bytesWritten; + if (!WriteFile(fd_, data.data(), static_cast(data.size()), &bytesWritten, NULL)) { + throw std::system_error(GetLastError(), std::system_category(), "WriteFile failed"); + } + return static_cast(bytesWritten); +#else + ssize_t result = ::write(fd_, data.data(), data.size()); + if (result < 0) { + throw std::system_error(errno, std::generic_category(), "write failed"); + } + return result; +#endif +} + +std::vector SerialPort::read() { +#ifdef _WIN32 + std::vector buffer(256); + DWORD bytesRead; + if (!ReadFile(fd_, buffer.data(), static_cast(buffer.size()), &bytesRead, NULL)) { + throw std::system_error(GetLastError(), std::system_category(), "ReadFile failed"); + } + buffer.resize(bytesRead); + return buffer; +#else + std::vector buffer(256); + ssize_t n = ::read(fd_, buffer.data(), buffer.size()); + if (n > 0) { + buffer.resize(n); + return buffer; + } + return {}; +#endif +} + +void SerialPort::close() { +#ifdef _WIN32 + if (fd_ != INVALID_HANDLE_VALUE) { + CloseHandle(fd_); + fd_ = INVALID_HANDLE_VALUE; + } +#else + if (fd_ >= 0) { + ::close(fd_); + fd_ = -1; + } +#endif +} + +speed_t SerialPort::getBaudRate(int baudrate) { +#ifdef _WIN32 + // Windows直接使用数值波特率 + return baudrate; +#else + switch (baudrate) { + case 50: return B50; + case 75: return B75; + case 110: return B110; + case 134: return B134; + case 150: return B150; + case 200: return B200; + case 300: return B300; + case 600: return B600; + case 1200: return B1200; + case 1800: return B1800; + case 2400: return B2400; + case 4800: return B4800; + case 9600: return B9600; + case 19200: return B19200; + case 38400: return B38400; + case 57600: return B57600; + case 115200: return B115200; + case 230400: return B230400; + case 460800: return B460800; + case 921600: return B921600; + case 1000000: return B1000000; + case 2000000: return B2000000; + case 4000000: return B4000000; + default: + throw std::invalid_argument("Unsupported baudrate"); + } +#endif +} + +void SerialPort::start_receiving(const ReceiveCallback &callback) { + running_ = true; + receiver_thread_ = std::thread([this, callback]() { + while (running_.load(std::memory_order_relaxed)) { + try { + auto data = read(); + if (!data.empty()) { + callback(data); + } + } + catch (const std::system_error &e) { + if (!running_) break; // 正常退出 + else throw; // 重新抛出其他错误 + } + } + }); +} + +void SerialPort::stop_receiving() { + running_.store(false); +#ifdef _WIN32 + // Windows通过关闭句柄唤醒阻塞的ReadFile + if (fd_ != INVALID_HANDLE_VALUE) { + CancelIoEx(fd_, NULL); + } +#else + // Linux通过关闭文件描述符唤醒阻塞的read + if (fd_ >= 0) { + ::close(fd_); + fd_ = -1; + } +#endif + if (receiver_thread_.joinable()) { + receiver_thread_.join(); + } +} + +ssize_t SerialPort::write(unsigned char *str, int size) { +#ifdef _WIN32 + DWORD bytesWritten; + if (!WriteFile(fd_, str, static_cast(size), &bytesWritten, NULL)) { + throw std::system_error(GetLastError(), std::system_category(), "WriteFile failed"); + } + return static_cast(bytesWritten); +#else + ssize_t result = ::write(fd_, str, size); + if (result < 0) { + throw std::system_error(errno, std::generic_category(), "write failed"); + } + return result; +#endif +} + +ssize_t SerialPort::write(const std::string &data) { +#ifdef _WIN32 + DWORD bytesWritten; + if (!WriteFile(fd_, data.data(), static_cast(data.size()), &bytesWritten, NULL)) { + throw std::system_error(GetLastError(), std::system_category(), "WriteFile failed"); + } + return static_cast(bytesWritten); +#else + ssize_t result = ::write(fd_, data.data(), data.size()); + if (result < 0) { + throw std::system_error(errno, std::generic_category(), "write failed"); + } + return result; +#endif +} \ No newline at end of file diff --git a/Serial/SerialPort.h b/Serial/SerialPort.h new file mode 100644 index 0000000..9b9b369 --- /dev/null +++ b/Serial/SerialPort.h @@ -0,0 +1,64 @@ +#ifndef ATCMD_SERIALPORT_H +#define ATCMD_SERIALPORT_H + +#include +#include +#include +#include +#include + +#ifdef _WIN32 +#include +using speed_t = unsigned int; +#else +#include +#include +#include +#endif + +class SerialPort { +public: + // 处理接收数据函数模板 + using ReceiveCallback = std::function &)>; + + // 打开串口设备 + SerialPort(const std::string &device, int baudrate); + + ~SerialPort(); + + // 配置串口参数 + void configure(int baudrate, int fd); + + // 发送数据 + ssize_t write(const std::vector &data); + + ssize_t write(const std::string &data); + + ssize_t write(unsigned char *str, int size); + + // 开始接收线程 + void start_receiving(const ReceiveCallback &callback); + + // 停止接收线程 + void stop_receiving(); + + void close(); + +private: +#ifdef _WIN32 + HANDLE fd_ = INVALID_HANDLE_VALUE; +#else + int fd_ = -1; +#endif + std::atomic running_; + std::thread receiver_thread_; + + // 接收数据 + std::vector read(); + + //获取波特率 + speed_t getBaudRate(int baudrate); +}; + + +#endif //ATCMD_SERIALPORT_H diff --git a/Socket/NetworkRelated.h b/Socket/NetworkRelated.h new file mode 100644 index 0000000..daeb301 --- /dev/null +++ b/Socket/NetworkRelated.h @@ -0,0 +1,51 @@ +#ifndef LXZL_NETWORKRELATED_H +#define LXZL_NETWORKRELATED_H + +#include +// 平台检测 +#ifdef _WIN32 +#include +#include +#else +#include +#include +#include +#include +#include +#include +#endif + +// 平台兼容类型定义 +#ifdef _WIN32 +using socklen_t = int; +using socket_t = SOCKET; +constexpr socket_t INVALID_SOCKET_VALUE = INVALID_SOCKET; +#else +using socket_t = int; +constexpr socket_t INVALID_SOCKET_VALUE = -1; +#define SOCKET_ERROR (-1) +#endif + + + +// Windows平台初始化 +#ifdef _WIN32 + +class WSAInitializer { +public: + WSAInitializer() { + WSADATA wsaData; + if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { + throw std::runtime_error("WSAStartup failed"); + } + } + + ~WSAInitializer() { + WSACleanup(); + } +}; + +static WSAInitializer wsa_initializer; +#endif + +#endif //LXZL_NETWORKRELATED_H diff --git a/Socket/TCP.cpp b/Socket/TCP.cpp new file mode 100644 index 0000000..c6fcc45 --- /dev/null +++ b/Socket/TCP.cpp @@ -0,0 +1,156 @@ +#include "TCP.h" + +void TCPSocket::create_socket() { + sockfd_ = socket(AF_INET, SOCK_STREAM, 0); + if (sockfd_ == INVALID_SOCKET_VALUE) { + throw std::runtime_error("Socket creation failed"); + } +} + +void TCPSocket::close_socket() { + if (sockfd_ != INVALID_SOCKET_VALUE) { +#ifdef _WIN32 + closesocket(sockfd_); +#else + close(sockfd_); +#endif + sockfd_ = INVALID_SOCKET_VALUE; + } + connected_.store(false); +} + +TCPSocket::~TCPSocket() { + close_socket(); +} + +bool TCPSocket::is_connected() const { return connected_.load(); } + +void TCPClient::connect(const std::string &ip, uint16_t port) { + create_socket(); + + sockaddr_in addr{}; + addr.sin_family = AF_INET; + addr.sin_port = htons(port); + inet_pton(AF_INET, ip.c_str(), &addr.sin_addr); + + if (::connect(sockfd_, (sockaddr *) &addr, sizeof(addr)) != 0) { + close_socket(); + throw std::runtime_error("Connection failed"); + } + connected_.store(true); +} + +size_t TCPClient::send(const void *data, size_t size) { +#ifdef _WIN32 + auto sent = ::send(sockfd_, (const char *) data, (int) size, 0); +#else + auto sent = ::send(sockfd_, data, size, 0); +#endif + + if (sent == SOCKET_ERROR) { + connected_.store(false); + throw std::runtime_error("Send failed"); + } + return static_cast(sent); +} + +size_t TCPClient::send(const std::string &data) { +#ifdef _WIN32 + auto sent = ::send(sockfd_, data.c_str(), static_cast(data.size()), 0); +#else + auto sent = ::send(sockfd_, data.c_str(), data.size(), 0); +#endif + + if (sent == SOCKET_ERROR) { + connected_.store(false); + throw std::runtime_error("Send failed"); + } + return static_cast(sent); +} + +size_t TCPClient::receive(void *buffer, size_t buffer_size) { +#ifdef _WIN32 + auto received = ::recv(sockfd_, (char *) buffer, (int) buffer_size, 0); +#else + auto received = ::recv(sockfd_, buffer, buffer_size, 0); +#endif + + if (received == 0) { + connected_.store(false); + return 0; + } + if (received == SOCKET_ERROR) { + connected_.store(false); + throw std::runtime_error("Receive failed"); + } + return static_cast(received); +} + +void TCPServer::listen(uint16_t port, int backlog) { + create_socket(); + + sockaddr_in addr{}; + addr.sin_family = AF_INET; + addr.sin_port = htons(port); + addr.sin_addr.s_addr = INADDR_ANY; + + if (bind(sockfd_, (sockaddr *) &addr, sizeof(addr)) != 0) { + close_socket(); + throw std::runtime_error("Bind failed"); + } + + if (::listen(sockfd_, backlog) != 0) { + close_socket(); + throw std::runtime_error("Listen failed"); + } +} + +std::shared_ptr TCPServer::accept() { + sockaddr_in client_addr{}; + socklen_t addr_len = sizeof(client_addr); + + auto client_sock = ::accept(sockfd_, (sockaddr *) &client_addr, &addr_len); + if (client_sock == INVALID_SOCKET_VALUE) { + throw std::runtime_error("Accept failed"); + } + + auto client = std::make_shared(); + client->sockfd_ = client_sock; + client->connected_.store(true); + return client; +} + +void AsyncTCPClient::start_async() { + running_.store(true); + recv_thread_ = std::thread([this]() { + std::vector buffer(4096); + while (running_.load()) { + try { + auto size = receive(buffer.data(), buffer.size()); + if (size > 0) { + std::lock_guard lock(queue_mutex_); + recv_queue_.emplace(buffer.begin(), buffer.begin() + static_cast(size)); + } + } + catch (...) { + break; + } + } + }); +} + +bool AsyncTCPClient::try_pop(std::vector &data) { + std::lock_guard lock(queue_mutex_); + if (recv_queue_.empty()) return false; + data = std::move(recv_queue_.front()); + recv_queue_.pop(); + return true; +} + +AsyncTCPClient::~AsyncTCPClient() { + running_.store(false); + if (recv_thread_.joinable()) { + recv_thread_.join(); + } + close_socket(); +} diff --git a/Socket/TCP.h b/Socket/TCP.h new file mode 100644 index 0000000..bc61125 --- /dev/null +++ b/Socket/TCP.h @@ -0,0 +1,79 @@ +#ifndef LXZL_TCP_H +#define LXZL_TCP_H + +#include "NetworkRelated.h" + +#include +#include +#include +#include +#include +#include + +/** + * TCP套接字 + */ +class TCPSocket { +public: + /** 创建套接字 */ + void create_socket(); + + /** 关闭套接字 */ + void close_socket(); + + virtual ~TCPSocket(); + + /** 套接字状态 */ + bool is_connected() const; + +public: + socket_t sockfd_ = INVALID_SOCKET_VALUE; + std::atomic connected_{false}; +}; + +/** + * TCP客户端 + */ +class TCPClient : public TCPSocket { +public: + /** 建立链接 */ + void connect(const std::string &ip, uint16_t port); + + /** 发送数据 */ + size_t send(const void *data, size_t size); + + size_t send(const std::string &data); + + /** 接收数据,返回数据长度 */ + size_t receive(void *buffer, size_t buffer_size); +}; + +/** + * TCP服务端 + */ +class TCPServer : public TCPSocket { +public: + void listen(uint16_t port, int backlog = SOMAXCONN); + + std::shared_ptr accept(); +}; + +// 异步客户端(生产者-消费者模式) +class AsyncTCPClient : public TCPClient { +public: + void start_async(); + + bool try_pop(std::vector &data); + + ~AsyncTCPClient() override; + +private: + std::thread recv_thread_; + std::mutex queue_mutex_; + std::condition_variable queue_cv_; + std::queue> recv_queue_; + std::atomic running_{false}; +}; + + +#endif //LXZL_TCP_H diff --git a/Socket/UDP.cpp b/Socket/UDP.cpp new file mode 100644 index 0000000..0db32de --- /dev/null +++ b/Socket/UDP.cpp @@ -0,0 +1,207 @@ +#include "UDP.h" + +#include +#include + +void UDPSocketBase::create_socket() { + while (true) { + sockfd_ = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); +#if defined(_WIN32) + if (sockfd_ != INVALID_SOCKET_VALUE) { + break; + } +#else + if (sockfd_ >= 0) { + break; + } +#endif + } +} + +void UDPSocketBase::create_socket(socket_t socket) { + sockfd_ = socket; +} + +void UDPSocketBase::set_nonblock(bool enable) { + u_long ctl = enable ? 1 : 0; +#if defined(_WIN32) + ioctlsocket(sockfd_, FIONBIO, &ctl) == 0; +#else + ioctl(sockfd_, FIONBIO, &ctl) == 0; +#endif + is_nonblock_ = enable; +} + +void UDPSocketBase::bind_socket(const sockaddr_in &addr) const { + if (bind(sockfd_, (struct sockaddr *) &addr, sizeof(addr)) != 0) { + throw std::runtime_error("Bind failed"); + } +} + +UDPSocketBase::~UDPSocketBase() { + if (sockfd_ != INVALID_SOCKET_VALUE) { +#ifdef _WIN32 + closesocket(sockfd_); +#else + close(sockfd_); +#endif + } +} + +UDPSender::UDPSender(socket_t socket, bool nonblock) { + if (socket != INVALID_SOCKET_VALUE) { + create_socket(socket); + } + else { + create_socket(); + } + set_nonblock(nonblock); +} + +void UDPSender::set_destination(const std::string &ip, uint16_t port) { + dstIp = ip; + dstPort = port; + dest_addr_.sin_family = AF_INET; + dest_addr_.sin_port = htons(port); +#if defined(_WIN32_WINNT) && _WIN32_WINNT < 0x600 + dest_addr_.sin_addr.S_un.S_addr = inet_addr(ip.c_str()); +#else + inet_pton(AF_INET, ip.c_str(), &dest_addr_.sin_addr); +#endif +} + +void UDPSender::set_source(const std::string &ip, uint16_t port) { + sockaddr_in addr{}; + addr.sin_family = AF_INET; + addr.sin_port = htons(port); +#if defined(_WIN32_WINNT) && _WIN32_WINNT < 0x600 + addr.sin_addr.S_un.S_addr = inet_addr(ip.c_str()); +#else + inet_pton(AF_INET, ip.c_str(), &addr.sin_addr); +#endif + bind_socket(addr); +} + +size_t UDPSender::send(const std::vector &data) { + auto sent = sendto(sockfd_, + reinterpret_cast(data.data()), + static_cast(data.size()), + 0, + (struct sockaddr *) &dest_addr_, + sizeof(dest_addr_)); + + if (sent == SOCKET_ERROR) { + throw std::runtime_error("Send failed"); + } + return static_cast(sent); +} + +size_t UDPSender::send(const std::string &data) { + auto sent = sendto(sockfd_, + reinterpret_cast(data.data()), + static_cast(data.size()), + 0, + (struct sockaddr *) &dest_addr_, + sizeof(dest_addr_)); + + if (sent == SOCKET_ERROR) { + throw std::runtime_error("Send failed"); + } + return static_cast(sent); +} + +size_t UDPSender::send(uint8_t *data, size_t size) { + int nleft, nwritten; + const char *ptr; + + ptr = (char *) data; /* can't do pointer arithmetic on void* */ + nleft = size; + while (nleft > 0) { +#if defined(_WIN32) + if ((nwritten = sendto(sockfd_, ptr, nleft, 0, (const struct sockaddr *) &dest_addr_, sizeof(dest_addr_))) <= 0) +#else + if ((nwritten = sendto(sockfd_, ptr, nleft, MSG_NOSIGNAL, (const struct sockaddr *) &dest_addr_, + sizeof(struct sockaddr))) <= 0) +#endif + { + if (!(errno == EWOULDBLOCK || errno == EAGAIN || errno == EINTR)) + return -1; /* error */ + else + continue; + } + + nleft -= nwritten; + ptr += nwritten; + } + + return (size); +} + + +UDPReceiver::UDPReceiver(uint16_t port, bool nonblock, size_t buffer_size) + : buffer_(buffer_size), running_(false), srcPort(port) { + create_socket(); + + sockaddr_in addr{}; + addr.sin_family = AF_INET; + addr.sin_port = htons(port); + addr.sin_addr.s_addr = INADDR_ANY; + + bind_socket(addr); + set_nonblock(nonblock); +} + +void UDPReceiver::start_receiving(const UDPReceiver::ReceiveCallback &callback) { + running_ = true; + receiver_thread_ = std::thread([this, callback]() { + while (running_.load(std::memory_order_relaxed)) { + try { + auto result = receive(); + ssize_t size = result.first; + auto &from = result.second; + if (size > 0) { + std::vector data(buffer_.begin(), + buffer_.begin() + size); + callback(data, from.first, from.second); + } + } + catch (const std::runtime_error &e) { + if (is_nonblock_) continue; + throw; + } + } + }); +} + +void UDPReceiver::stop_receiving() { + running_.store(false); + if (receiver_thread_.joinable()) { + receiver_thread_.join(); + } +} + +std::pair> UDPReceiver::receive() { + sockaddr_in from_addr{}; + socklen_t from_len = sizeof(from_addr); +#ifdef _WIN32 + DWORD timeout = UDPTimeout * 1000; // 3秒(单位:毫秒) + setsockopt(sockfd_, SOL_SOCKET, SO_RCVTIMEO, (const char *) &timeout, sizeof(timeout)); +#else + struct timeval tv; + tv.tv_sec = UDPTimeout; // 秒 + tv.tv_usec = 0; // 微秒 + setsockopt(sockfd_, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); +#endif + auto size = recvfrom(sockfd_, + reinterpret_cast(buffer_.data()), + static_cast(buffer_.size()), + 0, + (struct sockaddr *) &from_addr, + &from_len); + + if (size == SOCKET_ERROR) { + throw std::runtime_error("Receive Timeout"); + } + + return {size, {from_addr, from_len}}; +} diff --git a/Socket/UDP.h b/Socket/UDP.h new file mode 100644 index 0000000..f69df4b --- /dev/null +++ b/Socket/UDP.h @@ -0,0 +1,95 @@ +#ifndef LXZL_UDP_H +#define LXZL_UDP_H + +#include "NetworkRelated.h" + +#include +#include +#include +#include +#include + +//定义UDP接收线程超时时间(秒) +#define UDPTimeout (3) + +/** + * UDP基类 + */ +class UDPSocketBase { +protected: + UDPSocketBase() : sockfd_(INVALID_SOCKET_VALUE), is_nonblock_(false) {} + + /** 创建套接字 */ + void create_socket(); + void create_socket(socket_t socket); + + /** 设置是否阻塞 */ + void set_nonblock(bool enable); + + /** 建立链接 */ + void bind_socket(const sockaddr_in &addr) const; + +public: + virtual ~UDPSocketBase(); + + socket_t sockfd_; +protected: + bool is_nonblock_; +}; + +/** + * UDP发送端 + */ +class UDPSender : public UDPSocketBase { +public: + explicit UDPSender(socket_t socket=INVALID_SOCKET_VALUE,bool nonblock = false); + + /** 设置目的地址 */ + void set_destination(const std::string &ip, uint16_t port); + + /** 设置源地址 */ + void set_source(const std::string &ip, uint16_t port); + + /** 发送 */ + size_t send(const std::vector &data); + size_t send(uint8_t *data, size_t size); + size_t send(const std::string &data); + + std::string dstIp; + uint16_t dstPort; + +private: + sockaddr_in dest_addr_{}; +}; + +/** + * UDP接收端 + */ +class UDPReceiver : public UDPSocketBase { +public: + /** 处理接收数据函数模板 */ + using ReceiveCallback = std::function &, sockaddr_in, socklen_t)>; + + /** 设置接收端口 */ + explicit UDPReceiver(uint16_t port, bool nonblock = false, size_t buffer_size = 4096); + + /** 开始接收线程 */ + void start_receiving(const ReceiveCallback &callback); + + /** 停止接收线程 */ + void stop_receiving(); + + uint16_t srcPort; + +private: + /** 接收函数 */ + std::pair> receive(); + +private: + std::vector buffer_; + std::atomic running_; + std::thread receiver_thread_; +}; + + +#endif //LXZL_UDP_H diff --git a/Test/LogTest.cpp b/Test/LogTest.cpp new file mode 100644 index 0000000..fcc1ac0 --- /dev/null +++ b/Test/LogTest.cpp @@ -0,0 +1,47 @@ +#include "Test.h" + +#include "ConfigParser.h" +#include "LogL.h" + +using namespace std; + +void Log_Test() { + unordered_map config; + configFromIni("ini\\config.ini", config); + //日志类型 + LogType tmpLogType = LTStd; + auto tmp = config.find("logType"); + if (tmp != config.end()) { + if (tmp->second == "udp") { + tmpLogType = LTUdp; + } + else if (tmp->second == "txt") { + tmpLogType = LTTxt; + } + else if (tmp->second == "std") { + tmpLogType = LTStd; + } + } + //日志地址 + string tmpLogPath; + tmp = config.find("logPath"); + if (tmp != config.end()) { + tmpLogPath = tmp->second; + } + //日志状态 + bool tmpLogStatus = true; + tmp = config.find("logStatus"); + if (tmp != config.end()) { + if (tmp->second == "sync") { + tmpLogStatus = true; + } + else { + tmpLogStatus = false; + } + } + LogL logL(tmpLogType, tmpLogStatus, tmpLogPath); +} + + + + diff --git a/Test/ParserTest.cpp b/Test/ParserTest.cpp new file mode 100644 index 0000000..3e868af --- /dev/null +++ b/Test/ParserTest.cpp @@ -0,0 +1,19 @@ +#include "Test.h" +#include "ConfigParser.h" + + +using namespace std; + +void Parser_Test() { + std::unordered_map configList; + auto status = configFromIni("ini/config.ini", configList); + if (status == CPSUCCESS) { + for (auto &item: configList) { + cout << item.first << "\r" << item.second << endl; + } + } + cout << "test:" << configList["test"] << endl; + cout << "test:" << configList["test"] << endl; + cout << "test:" << configList["test"] << endl; + +} \ No newline at end of file diff --git a/Test/SerialTest.cpp b/Test/SerialTest.cpp new file mode 100644 index 0000000..ab599b4 --- /dev/null +++ b/Test/SerialTest.cpp @@ -0,0 +1,59 @@ +#include "Test.h" +#include "SerialPort.h" + +void Serial_Test() { + + try { + // 创建两个串口实例(模拟双向通信) + SerialPort sender("/dev/pts/2", 115200); + SerialPort receiver("/dev/pts/3", 115200); + + // 设置接收回调 + auto callback = [](const std::vector &data) { + std::cout << "Received: "; + for (auto c: data) { + std::cout << static_cast(c); + } + std::cout << std::endl; + }; + + // 启动接收线程 + receiver.start_receiving(callback); + + // 发送测试数据 + std::cout << "Starting serial port test...\n"; + + // 测试1: 发送字符串 + std::string testStr = "Hello Serial Port!\n"; + sender.write(testStr); + std::cout << "Sent: " << testStr; + + // 测试2: 发送二进制数据 + std::vector binaryData = {0x41, 0x42, 0x43, 0x44, 0x45}; // ABCDE + sender.write(binaryData); + std::cout << "Sent binary data: ABCDE\n"; + + // 测试3: 发送大量数据 + std::vector largeData(1024); + for (int i = 0; i < 1024; i++) { + largeData[i] = i % 256; + } + sender.write(largeData); + std::cout << "Sent 1024 bytes of data\n"; + + // 等待用户输入结束测试 + std::cout << "Press Enter to exit..."; + std::cin.get(); + + // 清理 + receiver.stop_receiving(); + sender.close(); + receiver.close(); + + } + catch (const std::exception &e) { + std::cerr << "Error: " << e.what() << std::endl; + } +} + + diff --git a/Test/TcpTest.cpp b/Test/TcpTest.cpp new file mode 100644 index 0000000..cb68317 --- /dev/null +++ b/Test/TcpTest.cpp @@ -0,0 +1,55 @@ +#include "Test.h" + +#include "TCP.h" + +using namespace std; + +void Tcp_Test() { +// AsyncTCPClient client; +// client.connect("127.0.0.1", 9999); +// client.start_async(); +// while (client.is_connected()) { +// std::vector str; +// if (client.try_pop(str)) { +// cout << string(str.begin(), str.end()) << endl; +// } +// } + + try { + TCPClient client; + client.connect("192.168.80.1", 9999); + while (client.is_connected()) { + vector buffer(1024); + auto size = client.receive(buffer.data(), buffer.size()); + string info; + if (size > 0) { + info = std::string(buffer.begin(), buffer.begin() + static_cast(size)); + cout << info << endl; + } + if (info.find("stop") != string::npos) { + client.close_socket(); + } + } + } + catch (std::exception &e) { + cerr << e.what() << endl; + } + + + TCPServer tcpServer; + tcpServer.listen(9998); + auto client = tcpServer.accept(); + while (client->is_connected()) { + client->send("hello"); + vector buffer(1024); + auto size = client->receive(buffer.data(), buffer.size()); + string info; + if (size > 0) { + info = std::string(buffer.begin(), buffer.begin() + static_cast(size)); + cout << info << endl; + } + if (info.find("stop") != string::npos) { + client->close_socket(); + } + } +} \ No newline at end of file diff --git a/Test/Test.h b/Test/Test.h new file mode 100644 index 0000000..f9e1804 --- /dev/null +++ b/Test/Test.h @@ -0,0 +1,16 @@ +#ifndef LXZL_TEST_H +#define LXZL_TEST_H +#include + + +void Serial_Test(); + +void Log_Test(); + +void Parser_Test(); + +void Tcp_Test(); + +void Udp_Test(); + +#endif //LXZL_TEST_H diff --git a/Test/UdpTest.cpp b/Test/UdpTest.cpp new file mode 100644 index 0000000..4cd1b82 --- /dev/null +++ b/Test/UdpTest.cpp @@ -0,0 +1,29 @@ +#include "Test.h" +#include "UDP.h" + +using namespace std; + +void Udp_Test() { + //UDP + uint16_t port = 8900; + UDPReceiver udpReceiver(port); + udpReceiver.start_receiving([](const std::vector &date, sockaddr_in sockAdd, socklen_t socklen){ + string da(date.begin(), date.end()); + cout << inet_ntoa(sockAdd.sin_addr) << ":" << ntohs(sockAdd.sin_port) << endl; + cout << da << endl; + }); + UDPSender udpSenderA(udpReceiver.sockfd_); + udpSenderA.set_destination("127.0.0.1", 8200); + UDPSender udpSenderB(udpReceiver.sockfd_); + udpSenderB.set_destination("127.0.0.1", 8201); + UDPSender udpSenderC(udpReceiver.sockfd_); + udpSenderC.set_destination("127.0.0.1", 8200); + + + while (true) { + udpSenderA.send("helloA"); + udpSenderB.send("B"); + udpSenderC.send("C"); + _sleep(5000); + } +} \ No newline at end of file diff --git a/Thread/ThreadL.cpp b/Thread/ThreadL.cpp new file mode 100644 index 0000000..15abf6a --- /dev/null +++ b/Thread/ThreadL.cpp @@ -0,0 +1,3 @@ +#include "ThreadL.h" + + diff --git a/Thread/ThreadL.h b/Thread/ThreadL.h new file mode 100644 index 0000000..8e3c863 --- /dev/null +++ b/Thread/ThreadL.h @@ -0,0 +1,6 @@ +#ifndef LXZL_THREADL_H +#define LXZL_THREADL_H + + + +#endif //LXZL_THREADL_H diff --git a/config.ini b/config.ini new file mode 100644 index 0000000..ef32c1e --- /dev/null +++ b/config.ini @@ -0,0 +1,8 @@ +logType=txt +logPath=logs +logStatus=sync +;udp=192.168.10.229,100,32 +AReceive=8600 +AA=127.0.0.1,8200 +AB=127.0.0.1,8201 +AC=127.0.0.1,8200 \ No newline at end of file diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..a9f8c64 --- /dev/null +++ b/main.cpp @@ -0,0 +1,19 @@ +#include +#include "Test.h" + +using namespace std; + +int main() { + Parser_Test(); + + Log_Test(); + + Udp_Test(); + + Tcp_Test(); + + Serial_Test(); + + return 0; +} +