From 28811fbae7ed609969a7051624d40bffb9f7e40a Mon Sep 17 00:00:00 2001 From: lnk Date: Wed, 5 Mar 2025 17:47:47 +0800 Subject: [PATCH] finish develop --- cfg_parse/cfg_parser.cpp | 234 ++++++++++--------- json/create_json.cpp | 10 +- json/save2json.cpp | 21 +- json/save2json.h | 490 +++++++++++++++++++++------------------ mms/mms_process.c | 2 +- pt61850netd_pqfe.pro | 14 ++ 6 files changed, 422 insertions(+), 349 deletions(-) diff --git a/cfg_parse/cfg_parser.cpp b/cfg_parse/cfg_parser.cpp index 481d0c7..f406a0b 100644 --- a/cfg_parse/cfg_parser.cpp +++ b/cfg_parse/cfg_parser.cpp @@ -1038,11 +1038,11 @@ void init_config() { //20241212lnk添加多前置 if (g_front_seg_index != 0 && g_front_seg_num != 0) { MULTIPLE_NODE_FLAG = 1; - std::cout << "当前功能是多进程:" << g_front_seg_index << std::endl; + std::cout << "this is multiple process of index:" << g_front_seg_index << std::endl; } else{ MULTIPLE_NODE_FLAG = 0; - std::cout << "当前功能是单进程:" << std::endl; + std::cout << "this is single process" << std::endl; } //20250109lnk添加进程测试打印端口 @@ -5238,7 +5238,7 @@ int SendMessageToWeb(int socketClient, int iErrorCode) // sendLength = send(socketClient, strSendJson.c_str(), strSendJson.length() + 1, 0); if (-1 == sendLength) { - printf("服务端向客户端%d发送[%d]消息错误,错误消息:%s\n", socketClient, iErrorCode, strSendJson.c_str()); + printf("server to client[%d] send[%d] message error,error message:%s\n", socketClient, iErrorCode, strSendJson.c_str()); return -1; } @@ -11676,110 +11676,106 @@ void printLedgerinshell(const ied_usr_t& ied_usr, QIODevice* outputDevice) { ied_t* ied; ied = find_ied_from_dev_idx(ied_usr.dev_idx); - outputDevice->write("------------------------------------\n"); - outputDevice->write("|-- terminal_id: " + QByteArray(ied_usr.terminal_id) + "\n"); - outputDevice->write("|-- dev_index: " + QByteArray::number(ied_usr.dev_idx) + "\n"); - outputDevice->write("|-- dev_cpucount: " + QByteArray::number(ied->cpucount) + "\n"); - outputDevice->write("|-- dev_ip: " + QByteArray(ied->channel[0].addr_str) + "\n"); + outputDevice->write("\r\x1B[K");outputDevice->write("------------------------------------\n"); + outputDevice->write("\r\x1B[K");outputDevice->write("|-- terminal_id: " + QByteArray(ied_usr.terminal_id) + "\n"); + outputDevice->write("\r\x1B[K");outputDevice->write("|-- dev_index: " + QByteArray::number(ied_usr.dev_idx) + "\n"); + outputDevice->write("\r\x1B[K");outputDevice->write("|-- dev_cpucount: " + QByteArray::number(ied->cpucount) + "\n"); + outputDevice->write("\r\x1B[K");outputDevice->write("|-- dev_ip: " + QByteArray(ied->channel[0].addr_str) + "\n"); char portStr[20]; // 用于存放端口号的字符串 sprintf(portStr, "%u", ied->channel[0].port); // 将端口号转为字符串 - outputDevice->write("|-- dev_port: " + QByteArray(portStr) + "\n"); + outputDevice->write("\r\x1B[K");outputDevice->write("|-- dev_port: " + QByteArray(portStr) + "\n"); char statusStr[20]; // 用于存放状态的字符串 sprintf(statusStr, "%u", ied->channel[0].status); // 将连接状态转为字符串 - outputDevice->write("|-- dev_connect_status: " + QByteArray(statusStr) + "\n"); - - outputDevice->write("|-- dev_type: " + QByteArray(ied_usr.dev_type) + "\n"); - - - outputDevice->write("|-- dev_key: " + QByteArray(ied_usr.dev_key) + "\n"); - outputDevice->write("|-- dev_series: " + QByteArray(ied_usr.dev_series) + "\n"); - outputDevice->write("|-- dev_processNo: " + QByteArray(ied_usr.processNo) + "\n"); - outputDevice->write("|-- dev_flag: " + QByteArray::number(ied_usr.dev_flag) + "\n"); - - outputDevice->write("|-- last_call_wavelist_time: " + QByteArray::number(ied_usr.last_call_wavelist_time) + "\n"); - - outputDevice->write("|-- org_name: " + QByteArray(ied_usr.org_name) + "\n"); - outputDevice->write("|-- maint_name: " + QByteArray(ied_usr.maint_name) + "\n"); - outputDevice->write("|-- station_name: " + QByteArray(ied_usr.station_name) + "\n"); - outputDevice->write("|-- tmnl_factory: " + QByteArray(ied_usr.tmnl_factory) + "\n"); - outputDevice->write("|-- time: " + QByteArray::number(ied_usr.time) + "\n"); - outputDevice->write("|-- tmnl_status: " + QByteArray(ied_usr.tmnl_status) + "\n"); - outputDevice->write("|-- terminal_code: " + QByteArray(ied_usr.terminal_code) + "\n"); - outputDevice->write("|-- update_flag: " + QByteArray::number(ied_usr.update_flag) + "\n"); + outputDevice->write("\r\x1B[K");outputDevice->write("|-- dev_connect_status: " + QByteArray(statusStr) + "\n"); + outputDevice->write("\r\x1B[K");outputDevice->write("|-- dev_type: " + QByteArray(ied_usr.dev_type) + "\n"); + outputDevice->write("\r\x1B[K");outputDevice->write("|-- dev_key: " + QByteArray(ied_usr.dev_key) + "\n"); + outputDevice->write("\r\x1B[K");outputDevice->write("|-- dev_series: " + QByteArray(ied_usr.dev_series) + "\n"); + outputDevice->write("\r\x1B[K");outputDevice->write("|-- dev_processNo: " + QByteArray(ied_usr.processNo) + "\n"); + outputDevice->write("\r\x1B[K");outputDevice->write("|-- dev_flag: " + QByteArray::number(ied_usr.dev_flag) + "\n"); + outputDevice->write("\r\x1B[K");outputDevice->write("|-- last_call_wavelist_time: " + QByteArray::number(ied_usr.last_call_wavelist_time) + "\n"); + outputDevice->write("\r\x1B[K");outputDevice->write("|-- org_name: " + QByteArray(ied_usr.org_name) + "\n"); + outputDevice->write("\r\x1B[K");outputDevice->write("|-- maint_name: " + QByteArray(ied_usr.maint_name) + "\n"); + outputDevice->write("\r\x1B[K");outputDevice->write("|-- station_name: " + QByteArray(ied_usr.station_name) + "\n"); + outputDevice->write("\r\x1B[K");outputDevice->write("|-- tmnl_factory: " + QByteArray(ied_usr.tmnl_factory) + "\n"); + outputDevice->write("\r\x1B[K");outputDevice->write("|-- time: " + QByteArray::number(ied_usr.time) + "\n"); + outputDevice->write("\r\x1B[K");outputDevice->write("|-- tmnl_status: " + QByteArray(ied_usr.tmnl_status) + "\n"); + outputDevice->write("\r\x1B[K");outputDevice->write("|-- terminal_code: " + QByteArray(ied_usr.terminal_code) + "\n"); + outputDevice->write("\r\x1B[K");outputDevice->write("|-- update_flag: " + QByteArray::number(ied_usr.update_flag) + "\n"); // 打印每个LD_info的内容 for (int i = 0; i < 10; ++i) { if (strcmp(ied_usr.LD_info[i].mp_id, "") != 0) { - outputDevice->write("|-- LD_info[" + QByteArray::number(i) + "]:\n"); + outputDevice->write("\r\x1B[K");outputDevice->write("|-- LD_info[" + QByteArray::number(i) + "]:\n"); // name - outputDevice->write(" |-- name: " + QByteArray(ied_usr.LD_info[i].name) + "\n"); - outputDevice->write(" |-- LD_name: " + outputDevice->write("\r\x1B[K");outputDevice->write(" |-- name: " + QByteArray(ied_usr.LD_info[i].name) + "\n"); + outputDevice->write("\r\x1B[K");outputDevice->write(" |-- LD_name: " + (strlen(ied_usr.LD_info[i].LD_name) == 0 ? QByteArray("NA") : QByteArray(ied_usr.LD_info[i].LD_name)) + "\n"); - outputDevice->write(" |-- read_flag: " + QByteArray::number(ied_usr.LD_info[i].read_flag) + "\n"); + outputDevice->write("\r\x1B[K");outputDevice->write(" |-- read_flag: " + QByteArray::number(ied_usr.LD_info[i].read_flag) + "\n"); // index - outputDevice->write(" |-- line_id: " + QByteArray::number(ied_usr.LD_info[i].line_id) + "\n"); + outputDevice->write("\r\x1B[K");outputDevice->write(" |-- line_id: " + QByteArray::number(ied_usr.LD_info[i].line_id) + "\n"); // monitorledger - outputDevice->write(" |-- mp_id: " + QByteArray(ied_usr.LD_info[i].mp_id) + "\n"); - outputDevice->write(" |-- terminal_code: " + QByteArray(ied_usr.LD_info[i].terminal_code) + "\n"); - outputDevice->write(" |-- voltage_level: " + QByteArray(ied_usr.LD_info[i].voltage_level) + "\n"); - outputDevice->write(" |-- v_wiring_type: " + QByteArray(ied_usr.LD_info[i].v_wiring_type) + "\n"); - outputDevice->write(" |-- time: " + QByteArray::number(ied_usr.LD_info[i].time) + "\n"); - outputDevice->write(" |-- update_flag: " + QByteArray::number(ied_usr.LD_info[i].update_flag) + "\n"); - outputDevice->write(" |-- monitor_status: " + QByteArray(ied_usr.LD_info[i].monitor_status) + "\n"); + outputDevice->write("\r\x1B[K");outputDevice->write(" |-- mp_id: " + QByteArray(ied_usr.LD_info[i].mp_id) + "\n"); + outputDevice->write("\r\x1B[K");outputDevice->write(" |-- terminal_code: " + QByteArray(ied_usr.LD_info[i].terminal_code) + "\n"); + outputDevice->write("\r\x1B[K");outputDevice->write(" |-- voltage_level: " + QByteArray(ied_usr.LD_info[i].voltage_level) + "\n"); + outputDevice->write("\r\x1B[K");outputDevice->write(" |-- v_wiring_type: " + QByteArray(ied_usr.LD_info[i].v_wiring_type) + "\n"); + outputDevice->write("\r\x1B[K");outputDevice->write(" |-- time: " + QByteArray::number(ied_usr.LD_info[i].time) + "\n"); + outputDevice->write("\r\x1B[K");outputDevice->write(" |-- update_flag: " + QByteArray::number(ied_usr.LD_info[i].update_flag) + "\n"); + outputDevice->write("\r\x1B[K");outputDevice->write(" |-- monitor_status: " + QByteArray(ied_usr.LD_info[i].monitor_status) + "\n"); // count暂不打印数组 - outputDevice->write(" |-- rptcount: " + QByteArray::number(ied_usr.LD_info[i].rptcount) + "\n"); - outputDevice->write(" |-- logcount: " + QByteArray::number(ied_usr.LD_info[i].logcount) + "\n"); + outputDevice->write("\r\x1B[K");outputDevice->write(" |-- rptcount: " + QByteArray::number(ied_usr.LD_info[i].rptcount) + "\n"); + outputDevice->write("\r\x1B[K");outputDevice->write(" |-- logcount: " + QByteArray::number(ied_usr.LD_info[i].logcount) + "\n"); // rpt - outputDevice->write(" |-- rptRecvFlag: " + QByteArray::number(ied_usr.LD_info[i].rptRecvFlag) + "\n"); - outputDevice->write(" |-- rptRecvCheckFlag: " + QByteArray::number(ied_usr.LD_info[i].rptRecvCheckFlag) + "\n"); - outputDevice->write(" |-- rptPstRecvFlag: " + QByteArray::number(ied_usr.LD_info[i].rptPstRecvFlag) + "\n"); - outputDevice->write(" |-- rptPstRecvCheckFlag: " + QByteArray::number(ied_usr.LD_info[i].rptPstRecvCheckFlag) + "\n"); + outputDevice->write("\r\x1B[K");outputDevice->write(" |-- rptRecvFlag: " + QByteArray::number(ied_usr.LD_info[i].rptRecvFlag) + "\n"); + outputDevice->write("\r\x1B[K");outputDevice->write(" |-- rptRecvCheckFlag: " + QByteArray::number(ied_usr.LD_info[i].rptRecvCheckFlag) + "\n"); + outputDevice->write("\r\x1B[K");outputDevice->write(" |-- rptPstRecvFlag: " + QByteArray::number(ied_usr.LD_info[i].rptPstRecvFlag) + "\n"); + outputDevice->write("\r\x1B[K");outputDevice->write(" |-- rptPstRecvCheckFlag: " + QByteArray::number(ied_usr.LD_info[i].rptPstRecvCheckFlag) + "\n"); // rtdata - outputDevice->write(" |-- real_data: " + QByteArray::number(ied_usr.LD_info[i].real_data) + "\n"); - outputDevice->write(" |-- soe_data: " + QByteArray::number(ied_usr.LD_info[i].soe_data) + "\n"); - outputDevice->write(" |-- limit: " + QByteArray::number(ied_usr.LD_info[i].limit) + "\n"); - outputDevice->write(" |-- count: " + QByteArray::number(ied_usr.LD_info[i].count) + "\n"); + outputDevice->write("\r\x1B[K");outputDevice->write(" |-- real_data: " + QByteArray::number(ied_usr.LD_info[i].real_data) + "\n"); + outputDevice->write("\r\x1B[K");outputDevice->write(" |-- soe_data: " + QByteArray::number(ied_usr.LD_info[i].soe_data) + "\n"); + outputDevice->write("\r\x1B[K");outputDevice->write(" |-- limit: " + QByteArray::number(ied_usr.LD_info[i].limit) + "\n"); + outputDevice->write("\r\x1B[K");outputDevice->write(" |-- count: " + QByteArray::number(ied_usr.LD_info[i].count) + "\n"); // RDRE - outputDevice->write(" |-- RDRE_FltNum: " + QByteArray::number(ied_usr.LD_info[i].RDRE_FltNum) + "\n"); + outputDevice->write("\r\x1B[K");outputDevice->write(" |-- RDRE_FltNum: " + QByteArray::number(ied_usr.LD_info[i].RDRE_FltNum) + "\n"); for (int j = 0; j < 256; ++j) { if (ied_usr.LD_info[i].FltNum[j] != 0) { - outputDevice->write(" |-- FltNum[" + QByteArray::number(j) + "]: " + outputDevice->write("\r\x1B[K");outputDevice->write(" |-- FltNum[" + QByteArray::number(j) + "]: " + QByteArray::number(ied_usr.LD_info[i].FltNum[j]) + "\n"); } } // QVVR - outputDevice->write(" |-- qvvr_idx: " + QByteArray::number(ied_usr.LD_info[i].qvvr_idx) + "\n"); - outputDevice->write(" |-- QVVRs:\n"); + outputDevice->write("\r\x1B[K");outputDevice->write(" |-- qvvr_idx: " + QByteArray::number(ied_usr.LD_info[i].qvvr_idx) + "\n"); + outputDevice->write("\r\x1B[K");outputDevice->write(" |-- QVVRs:\n"); for (int j = 0; j < 256; ++j) { if (ied_usr.LD_info[i].qvvr[j].used_status != 0) { - outputDevice->write(" |-- QVVR[" + QByteArray::number(j) + "]:\n"); - outputDevice->write(" |-- used_status: " + QByteArray::number(ied_usr.LD_info[i].qvvr[j].used_status) + "\n"); - outputDevice->write(" |-- QVVR_start: " + QByteArray::number(ied_usr.LD_info[i].qvvr[j].QVVR_start) + "\n"); - outputDevice->write(" |-- QVVR_type: " + QByteArray::number(ied_usr.LD_info[i].qvvr[j].QVVR_type) + "\n"); - outputDevice->write(" |-- QVVR_time: " + QByteArray::number(ied_usr.LD_info[i].qvvr[j].QVVR_time) + "\n"); - outputDevice->write(" |-- QVVR_PerTime: " + QByteArray::number(ied_usr.LD_info[i].qvvr[j].QVVR_PerTime) + "\n"); - outputDevice->write(" |-- QVVR_Amg: " + QByteArray::number(ied_usr.LD_info[i].qvvr[j].QVVR_Amg) + "\n"); - outputDevice->write(" |-- QVVR_Rptname: " + QByteArray(ied_usr.LD_info[i].qvvr[j].QVVR_Rptname) + "\n"); - outputDevice->write(" |-- timestamp: " + QByteArray::number(ied_usr.LD_info[i].qvvr[j].timestamp) + "\n"); + outputDevice->write("\r\x1B[K");outputDevice->write(" |-- QVVR[" + QByteArray::number(j) + "]:\n"); + outputDevice->write("\r\x1B[K");outputDevice->write(" |-- used_status: " + QByteArray::number(ied_usr.LD_info[i].qvvr[j].used_status) + "\n"); + outputDevice->write("\r\x1B[K");outputDevice->write(" |-- QVVR_start: " + QByteArray::number(ied_usr.LD_info[i].qvvr[j].QVVR_start) + "\n"); + outputDevice->write("\r\x1B[K");outputDevice->write(" |-- QVVR_type: " + QByteArray::number(ied_usr.LD_info[i].qvvr[j].QVVR_type) + "\n"); + outputDevice->write("\r\x1B[K");outputDevice->write(" |-- QVVR_time: " + QByteArray::number(ied_usr.LD_info[i].qvvr[j].QVVR_time) + "\n"); + outputDevice->write("\r\x1B[K");outputDevice->write(" |-- QVVR_PerTime: " + QByteArray::number(ied_usr.LD_info[i].qvvr[j].QVVR_PerTime) + "\n"); + outputDevice->write("\r\x1B[K");outputDevice->write(" |-- QVVR_Amg: " + QByteArray::number(ied_usr.LD_info[i].qvvr[j].QVVR_Amg) + "\n"); + outputDevice->write("\r\x1B[K");outputDevice->write(" |-- QVVR_Rptname: " + QByteArray(ied_usr.LD_info[i].qvvr[j].QVVR_Rptname) + "\n"); + outputDevice->write("\r\x1B[K");outputDevice->write(" |-- timestamp: " + QByteArray::number(ied_usr.LD_info[i].qvvr[j].timestamp) + "\n"); } } } } - outputDevice->write("------------------------------------\n"); + outputDevice->write("\r\x1B[K");outputDevice->write("------------------------------------\n"); } // 打印所有设备信息或特定终端信息 void ledger(const char* terminal_id, QIODevice* outputDevice) { + outputDevice->write("\r\x1B[K"); outputDevice->write("print ledger in shell"); pthread_mutex_lock(&mtx); std::cout << "ledger()hold lock !!!!!!!!!!!" << std::endl; bool found = false; @@ -11790,20 +11786,25 @@ void ledger(const char* terminal_id, QIODevice* outputDevice) { if(ied != NULL){ ied_usr = (ied_usr_t*)ied->usr_ext; if (ied_usr != NULL && (terminal_id == NULL || strcmp(ied_usr->terminal_id, terminal_id) == 0)) { - //printLedgerinshell(*ied_usr, outputDevice); // 使用 QIODevice 输出 + printLedgerinshell(*ied_usr, outputDevice); // 使用 QIODevice 输出 //std::cout << "!!! print to log !!!"<< std::endl; //printLedger(*ied_usr); - found = true; + if(terminal_id != NULL && strcmp(ied_usr->terminal_id, terminal_id) == 0){ + found = true; + } + } } } - if (!found || terminal_id == NULL) { - std::cout << "该终端不存在: " << terminal_id << std::endl; - QByteArray msg = "该终端不存在: " + QByteArray(terminal_id ? terminal_id : "NULL") + "\n"; + pthread_mutex_unlock(&mtx); std::cout << "ledger()free lock !!!!!!!!!!!" << std::endl; + if (terminal_id != NULL && !found) { + std::cout << "terminal not exsist: " << terminal_id << std::endl; + QByteArray msg = "terminal not exsist: " + QByteArray(terminal_id) + "\n"; + outputDevice->write("\r\x1B[K"); outputDevice->write(msg); // 输出到 QIODevice } - pthread_mutex_unlock(&mtx); std::cout << "ledger()free lock !!!!!!!!!!!" << std::endl; + } //lnk20250210打印指定的变量名 @@ -11815,25 +11816,32 @@ void value_print(const char *variableName, QTcpSocket *clientSocket) { if (strcmp(variableName, "frontindex") == 0) { sprintf(buffer, "frontindex = %d", g_front_seg_index); // 将 int 转换为字符串 + clientSocket->write("\r\x1B[K"); clientSocket->write(buffer); // 发送字符串到客户端 } else if (strcmp(variableName, "remtable") == 0) { sprintf(buffer, "remtable = %d",g_pt61850app->chnl_counts); + clientSocket->write("\r\x1B[K"); clientSocket->write(buffer); } else if (strcmp(variableName, "iedcount") == 0) { sprintf(buffer, "g_node->n_clients = %d, ied config count = %d",g_node->n_clients ,IED_COUNT); + clientSocket->write("\r\x1B[K"); clientSocket->write(buffer); } else if (strcmp(variableName, "frontfun") == 0) { sprintf(buffer, "frontfun = %s", subdir); + clientSocket->write("\r\x1B[K"); clientSocket->write(buffer); } else if (strcmp(variableName, "log") == 0) { sprintf(buffer, "showinshellflag = %d,debugOutputEnabled = %d,normalOutputEnabled = %d,warnOutputEnabled = %d,errorOutputEnabled = %d", showinshellflag,debugOutputEnabled,normalOutputEnabled,warnOutputEnabled,errorOutputEnabled); + clientSocket->write("\r\x1B[K"); clientSocket->write(buffer); }else if (strcmp(variableName, "init") == 0) { sprintf(buffer, "INITFLAG = %d",INITFLAG); + clientSocket->write("\r\x1B[K"); clientSocket->write(buffer); }else { + clientSocket->write("\r\x1B[K"); clientSocket->write("Unknown variable name\n> "); } pthread_mutex_unlock(&mtx); std::cout << "value_print free lock !!!!!!!!!!!" << std::endl; @@ -11859,6 +11867,7 @@ pthread_mutex_t* getLogMutex(const QString& level) { void Worker::handleViewLogCommand(const QString& command, QTcpSocket* clientSocket) { QStringList parts = command.split(" "); if (parts.size() != 2) { + clientSocket->write("\r\x1B[K"); clientSocket->write("Usage: viewlog [ERROR|WARN|NORMAL|DEBUG]\n> "); clientSocket->flush(); return; @@ -11869,6 +11878,7 @@ void Worker::handleViewLogCommand(const QString& command, QTcpSocket* clientSock pthread_mutex_t* logMutex = getLogMutex(logLevel); if (!logList || !logMutex) { + clientSocket->write("\r\x1B[K"); clientSocket->write("Invalid log level! Use ERROR, WARN, NORMAL, or DEBUG.\n> "); clientSocket->flush(); return; @@ -11877,6 +11887,7 @@ void Worker::handleViewLogCommand(const QString& command, QTcpSocket* clientSock stopViewLog = false; activeClient = clientSocket; // 记录当前 shell socket + clientSocket->write("\r\x1B[K"); clientSocket->write(QString("Viewing logs for level: %1 (Press 'q' to exit)\n> ").arg(logLevel).toUtf8()); clientSocket->flush(); @@ -11900,6 +11911,7 @@ void Worker::handleViewLogCommand(const QString& command, QTcpSocket* clientSock pthread_mutex_unlock(logMutex); if (!logEntry.empty()) { + clientSocket->write("\r\x1B[K"); clientSocket->write((logEntry + "\n").c_str()); clientSocket->flush(); } @@ -11910,6 +11922,7 @@ void Worker::handleViewLogCommand(const QString& command, QTcpSocket* clientSock } // **3. 退出 `viewlog`,返回 Shell** + clientSocket->write("\r\x1B[K"); clientSocket->write("\nLog view stopped. Returning to shell.\n> "); clientSocket->flush(); } @@ -15289,12 +15302,20 @@ public: TeeStreamBuf() : m_originalBuf(NULL), m_level(LOGNORMAL) { + pthread_mutex_init(&m_mutex, NULL); } // 带参构造:直接初始化 TeeStreamBuf(std::streambuf* originalBuf, LogLevel level) : m_originalBuf(originalBuf), m_level(level) { + pthread_mutex_init(&m_mutex, NULL); + } + + // 析构函数:销毁互斥锁 + virtual ~TeeStreamBuf() + { + pthread_mutex_destroy(&m_mutex); } // 自定义 init(...) 函数:在同一个对象上重新设置 @@ -15302,7 +15323,9 @@ public: { m_originalBuf = originalBuf; m_level = level; + pthread_mutex_lock(&m_mutex); m_buffer.clear(); + pthread_mutex_unlock(&m_mutex); } protected: @@ -15330,97 +15353,100 @@ protected: return traits_type::eof(); } } - // 2) 存到我们的临时缓存 - m_buffer.push_back((char)ch); + // 2) 存到我们的临时缓存,注意加锁保护 + pthread_mutex_lock(&m_mutex); //防止多线程推入崩溃lnk20250305 + m_buffer.push_back(static_cast(ch)); // 3) 遇到换行就 flushBuffer() if (ch == '\n') { - flushBuffer(); + flushBuffer_locked(); } + pthread_mutex_unlock(&m_mutex); return ch; } private: - // 把 m_buffer 的内容一次性写入相应 list,并清空 - void flushBuffer() + // 内部版本:假定互斥锁已经被加锁 + void flushBuffer_locked() { if (m_buffer.empty()) { return; } - - // 根据等级 + 对应开关 → 写哪几个list + // 根据等级和对应开关,将 m_buffer 写入相应的 list switch (m_level) { - case LOGERROR: - - if (debugOutputEnabled) { - pthread_mutex_lock(&debugListMutex); - debugList.push_back(m_buffer); - pthread_mutex_unlock(&debugListMutex); - } + if (debugOutputEnabled) { + pthread_mutex_lock(&debugListMutex); + debugList.push_back(m_buffer); + pthread_mutex_unlock(&debugListMutex); + } else if (normalOutputEnabled) { pthread_mutex_lock(&normalListMutex); normalList.push_back(m_buffer); pthread_mutex_unlock(&normalListMutex); } - else if (warnOutputEnabled) { + else if (warnOutputEnabled) { pthread_mutex_lock(&warnListMutex); warnList.push_back(m_buffer); pthread_mutex_unlock(&warnListMutex); } - else if (errorOutputEnabled) { + else if (errorOutputEnabled) { pthread_mutex_lock(&errorListMutex); errorList.push_back(m_buffer); pthread_mutex_unlock(&errorListMutex); } - break; case LOGWARN: - - if (debugOutputEnabled) { - pthread_mutex_lock(&debugListMutex); - debugList.push_back(m_buffer); - pthread_mutex_unlock(&debugListMutex); - } + if (debugOutputEnabled) { + pthread_mutex_lock(&debugListMutex); + debugList.push_back(m_buffer); + pthread_mutex_unlock(&debugListMutex); + } else if (normalOutputEnabled) { pthread_mutex_lock(&normalListMutex); normalList.push_back(m_buffer); pthread_mutex_unlock(&normalListMutex); } - else if (warnOutputEnabled) { + else if (warnOutputEnabled) { pthread_mutex_lock(&warnListMutex); warnList.push_back(m_buffer); pthread_mutex_unlock(&warnListMutex); } - break; case LOGNORMAL: - if (debugOutputEnabled) { - pthread_mutex_lock(&debugListMutex); - debugList.push_back(m_buffer); - pthread_mutex_unlock(&debugListMutex); - } + if (debugOutputEnabled) { + pthread_mutex_lock(&debugListMutex); + debugList.push_back(m_buffer); + pthread_mutex_unlock(&debugListMutex); + } else if (normalOutputEnabled) { pthread_mutex_lock(&normalListMutex); normalList.push_back(m_buffer); pthread_mutex_unlock(&normalListMutex); } - break; } - m_buffer.clear(); } + // 对外接口,内部对 m_buffer 加锁 + void flushBuffer() + { + pthread_mutex_lock(&m_mutex); + flushBuffer_locked(); + pthread_mutex_unlock(&m_mutex); + } + private: // 禁止自动生成的赋值函数 - TeeStreamBuf& operator=(const TeeStreamBuf&); // 不实现 + TeeStreamBuf& operator=(const TeeStreamBuf&); private: std::streambuf* m_originalBuf; LogLevel m_level; std::string m_buffer; + pthread_mutex_t m_mutex; }; // ------------------ 全局Tee对象(避免重复赋值) ------------------ diff --git a/json/create_json.cpp b/json/create_json.cpp index 6a4e242..7cf4589 100644 --- a/json/create_json.cpp +++ b/json/create_json.cpp @@ -3808,7 +3808,7 @@ char* Get_xmlpath(char* devtype) if (xmlinfo_list.contains(type)) { cout << "!!!!!!!!!! xmlinfo_list.contains(devtype) == 1 !!!!!!!!!!!" << endl; QByteArray byteArray = xmlinfo_list[devtype]->xmlbase.MODEL_ID.toLocal8Bit(); - char* charArray = new char[byteArray.size()]; + char* charArray = new char[byteArray.size()+1];//分配内存时+1防止内存泄漏lnk20250305 memcpy(charArray, byteArray.data(), byteArray.size()); charArray[byteArray.size()] = '\0'; return charArray; @@ -3830,7 +3830,7 @@ char* Get_IED(char* devtype) ied.append(xmlinfo_list[devtype]->xmlcfg.LDevicePrefix); ied.append("%d"); QByteArray byteArray = ied.toLocal8Bit(); - char* charArray = new char[byteArray.size()]; + char* charArray = new char[byteArray.size()+1];//分配内存时+1防止内存泄漏lnk20250305 memcpy(charArray, byteArray.data(), byteArray.size()); charArray[byteArray.size()] = '\0'; return charArray; @@ -3844,7 +3844,7 @@ char* Get_IED(char* devtype) ied.append(xmlcfg.LDevicePrefix); ied.append("%d"); QByteArray byteArray = ied.toLocal8Bit(); - char* charArray = new char[byteArray.size()]; + char* charArray = new char[byteArray.size()+1];//分配内存时+1防止内存泄漏lnk20250305 memcpy(charArray, byteArray.data(), byteArray.size()); charArray[byteArray.size()] = '\0'; return charArray; @@ -3859,7 +3859,7 @@ char* Get_LDevice(char* devtype) ied.append(xmlinfo_list[devtype]->xmlcfg.LDevicePrefix);//使用解析列表的终端前缀 ied.append("%d"); QByteArray byteArray = ied.toLocal8Bit(); - char* charArray = new char[byteArray.size()]; + char* charArray = new char[byteArray.size()+1];//分配内存时+1防止内存泄漏lnk20250305 memcpy(charArray, byteArray.data(), byteArray.size()); charArray[byteArray.size()] = '\0'; return charArray; @@ -3871,7 +3871,7 @@ char* Get_LDevice(char* devtype) ied.append(xmlcfg.LDevicePrefix);//使用默认解析配置的终端前缀 ied.append("%d"); QByteArray byteArray = ied.toLocal8Bit(); - char* charArray = new char[byteArray.size()]; + char* charArray = new char[byteArray.size()+1];//分配内存时+1防止内存泄漏lnk20250305 memcpy(charArray, byteArray.data(), byteArray.size()); charArray[byteArray.size()] = '\0'; return charArray; diff --git a/json/save2json.cpp b/json/save2json.cpp index e861576..fd78d8a 100644 --- a/json/save2json.cpp +++ b/json/save2json.cpp @@ -608,7 +608,7 @@ void KafkaSendThread::run() pthread_mutex_lock(&debugListMutex); if (!debugList.empty()) { log_gotten = true; - log_send.strText = QString::fromStdString(errorList.front()); + log_send.strText = QString::fromStdString(debugList.front());//请确保list正确 // 检查是否为空字符串(去掉空白字符后是否为空) if (log_send.strText.trimmed().isEmpty()) { debugList.pop_front(); // 直接丢弃这条日志 @@ -1234,10 +1234,14 @@ void parse_set(const std::string& json_str) { for (int i = 0; i < data_size; i++) { cJSON* item = cJSON_GetArrayItem(data, i); - std::string fun = cJSON_GetObjectItem(item, "fun")->valuestring; - std::string ip = cJSON_GetObjectItem(item, "ip")->valuestring; - std::string frontType = cJSON_GetObjectItem(item, "frontType")->valuestring; - int proindex = cJSON_GetObjectItem(item, "proindex")->valueint; + std::string fun = cJSON_GetObjectItem(item, "fun")->valuestring?cJSON_GetObjectItem(item, "fun")->valuestring:"NULL"; + std::string ip = cJSON_GetObjectItem(item, "ip")->valuestring?cJSON_GetObjectItem(item, "ip")->valuestring:"NULL"; + std::string frontType = cJSON_GetObjectItem(item, "frontType")->valuestring?cJSON_GetObjectItem(item, "frontType")->valuestring:"NULL"; + cJSON *index_item = cJSON_GetObjectItem(item, "proindex"); + int proindex = 0; // 默认值 + if (index_item != NULL && index_item->type == cJSON_Number) { + proindex = index_item->valueint; + } //校验数据 if((fun == "start" || fun == "delete") && @@ -2837,11 +2841,6 @@ void try_start_http_thread() int try_start_mqtest_thread(int argc, char *argv[]) { //不使用简单的循环线程,而是启动一个app,不仅执行循环线程,而且可以连接输入 - /*static int mqtest_thread_created = 0; - if (!mqtest_thread_created) { - mqtestThrd.start(); - mqtest_thread_created = 1; - }*/ //安装qt打印 qInstallMsgHandler(myQtMsgHandler); @@ -2863,8 +2862,6 @@ int try_start_mqtest_thread(int argc, char *argv[]) // 启动线程 thread->start(); - //std::cout << "start_mqtest"<start(60000); // 每60秒触发一次 - //开启另一个周期函数用来替换主线程的监控 + // 开启另一个周期函数用来替换主线程的监控 QTimer *monitorTimer = new QTimer(this); connect(monitorTimer, SIGNAL(timeout()), this, SLOT(doMonitorTask())); monitorTimer->start(1000); // 每1秒触发一次 - std::cout << "Timer started, event loop running in thread: " << QThread::currentThreadId() << std::endl; + std::cout << "Timer started, event loop running in thread: " + << QThread::currentThreadId() << std::endl; qDebug() << "Timer started, event loop running in thread:" << QThread::currentThreadId(); } + /** + * @brief 停止服务器 + */ void stopServer() { // 停止服务器并清理资源 if (server) { @@ -199,12 +221,18 @@ public slots: } } + /** + * @brief 设置TEST_NUM + */ void setTestNum(int num) { QMutexLocker locker(&mutex); TEST_NUM = num; } private slots: + /** + * @brief 定时任务 + */ void doPeriodicTask() { QMutexLocker locker(&mutex); std::cout << "Executing TEST_NUM is " << TEST_NUM << std::endl; @@ -217,10 +245,16 @@ private slots: } } + /** + * @brief 监控任务 + */ void doMonitorTask() { doMonitorTaskmain(); } + /** + * @brief 当有新客户端连接时处理 + */ void onNewConnection() { if (!server) return; @@ -228,22 +262,24 @@ private slots: qDebug() << "New connection established!"; std::cout << "New connection established!\n"; - // 当有数据可读时,进入 onReadyRead() + // 绑定 readyRead / disconnected connect(clientSocket, SIGNAL(readyRead()), this, SLOT(onReadyRead())); - // 当客户端断开时,自动清理 socket connect(clientSocket, SIGNAL(disconnected()), clientSocket, SLOT(deleteLater())); - // 向客户端发送提示符 + // 发送 Telnet 协商 + sendTelnetNegotiation(clientSocket); + + // 发送欢迎信息和提示符 if (clientSocket) { std::cout << "clientSocket OK\n"; - clientSocket->write("Welcome to the test shell. Type 'help' for available commands.\n> "); - clientSocket->flush(); // 确保消息立即发送 + clientSocket->write("\r\x1B[K"); + clientSocket->write("Welcome to the test shell. Type 'help' for available commands.\r\n"); + printPrompt(clientSocket); // 统一打印提示符 } } /** - * @brief 逐字节处理Telnet输入,识别方向键(上下)、退格、回车等 - * 当按下回车时,将当前行内容视为一条命令交给 processCommand 解析。 + * @brief 处理客户端发送的Telnet数据 */ void onReadyRead() { QTcpSocket *clientSocket = qobject_cast(sender()); @@ -253,72 +289,87 @@ private slots: } QByteArray data = clientSocket->readAll(); - - // 逐字节处理输入 for (int i = 0; i < data.size(); ++i) { - char c = data[i]; + unsigned char c = static_cast(data[i]); - if (c == 'q') { // ? 用户输入 `q` 退出 `viewlog` + // 如果检测到 IAC(255),说明是 Telnet 协商指令 + if (c == IAC) { + // 简单跳过 TELDO/DONT/WILL/WONT + option + if (i + 1 < data.size()) { + unsigned char cmd = static_cast(data[i+1]); + if (cmd == TELDO || cmd == DONT || cmd == WILL || cmd == WONT) { + i += 2; // 跳过这2字节 + } else { + // 遇到其它情况(比如IAC SB),此处仅简单跳过一个字节 + i += 1; + } + } + continue; + } + + // 1) 处理 'q' 退出 viewlog + if (c == 'q') { std::cout << "Received 'q' from shell socket! Exiting viewlog...\n"; if (activeClient == clientSocket) { - stopViewLog = true; // ? 让 `viewlog` 退出 - - clientSocket->write("\nLog view stopped. Returning to shell.\n> "); + stopViewLog = true; + clientSocket->write("\r\x1B[K"); + clientSocket->write("\r\nLog view stopped. Returning to shell.\r\n"); + printPrompt(clientSocket); + } + return; + } + + // 2) 回车换行:执行命令 + if (c == '\r' || c == '\n') { + if (!currentCommand.isEmpty()) { + // 加到历史 + if (commandHistory.isEmpty() || commandHistory.last() != currentCommand) { + commandHistory.append(currentCommand); + } + historyIndex = commandHistory.size(); + + // 执行命令时,忽略前后空白 + //QString trimmedCmd = currentCommand.trimmed(); + currentCommand.remove(0, 1); + processCommand(currentCommand, clientSocket); + + currentCommand.clear(); + } else { + // 空行 => 仅打印新的提示符 + printPrompt(clientSocket); + } + continue; + } + + // 3) 方向键 + if (c == '\x1b') { + if (i + 2 < data.size() && data[i+1] == '[') { + char arrow = data[i+2]; + if (arrow == 'A') { + handleUpArrow(clientSocket); + } else if (arrow == 'B') { + handleDownArrow(clientSocket); + } + i += 2; + } + continue; + } + + // 4) 退格键 + if (c == '\x7f' || c == '\b') { + if (!currentCommand.isEmpty()) { + currentCommand.chop(1); + // 回显退格 + clientSocket->write("\b \b"); clientSocket->flush(); } - return; // ? 立即返回,避免继续处理其他字符 - } - - switch (c) { - case '\r': - case '\n': - // ? 处理回车,执行命令 - if (!currentCommand.isEmpty()) { - if (commandHistory.isEmpty() || commandHistory.last() != currentCommand) { - commandHistory.append(currentCommand); - } - historyIndex = commandHistory.size(); // 指向最新一条之后 - - processCommand(currentCommand, clientSocket); - currentCommand.clear(); - } else { - clientSocket->write("\n> "); - clientSocket->flush(); - } - break; - - case '\x1b': - // ? 处理方向键 (上箭头 `\x1b[A`,下箭头 `\x1b[B`) - if (i + 2 < data.size() && data[i+1] == '[') { - char arrow = data[i+2]; - if (arrow == 'A') { - handleUpArrow(clientSocket); // **调用上箭头处理** - } else if (arrow == 'B') { - handleDownArrow(clientSocket); // **调用下箭头处理** - } - i += 2; // ? **跳过 ESC 序列 `\x1b[A` 或 `\x1b[B`** - continue; - } - break; - - case '\x7f': - case '\x08': - // ? 处理退格键 - if (!currentCommand.isEmpty()) { - currentCommand.chop(1); - clientSocket->write("\b \b"); - clientSocket->flush(); - } - break; - - default: - // ? 普通字符,追加到 `currentCommand` - currentCommand.append(c); - clientSocket->write(&c, 1); - clientSocket->flush(); - break; + continue; } + // 5) 普通字符 + currentCommand.append(static_cast(c)); + clientSocket->write((const char*)&c, 1); + clientSocket->flush(); } } @@ -326,195 +377,176 @@ signals: void serverError(); private: - // ====================== 新增日志功能 ========================= - bool stopViewLog; // ? 这里不需要 static,针对每个 client - QTcpSocket* activeClient; // 记录当前正在 `viewlog` 的客户端 + // ========== Telnet 协商函数 ========== + void sendTelnetNegotiation(QTcpSocket *socket) + { + // 发送 WILL ECHO / WILL SUPPRESS-GO-AHEAD / DONT LINEMODE + static const unsigned char will_echo[3] = { IAC, WILL, TELOPT_ECHO }; + static const unsigned char will_sga[3] = { IAC, WILL, TELOPT_SUPPRESS_GO_AHEAD }; + static const unsigned char dont_linemode[3] = { IAC, DONT, TELOPT_LINEMODE }; - // -------------------- - // 以下为新增的辅助函数 - // -------------------- + socket->write(reinterpret_cast(will_echo), 3); + socket->write(reinterpret_cast(will_sga), 3); + socket->write(reinterpret_cast(dont_linemode), 3); + socket->flush(); + } /** - * @brief 处理输入命令(完整的一行),即原先在 onReadyRead() 大量 if-else 的逻辑 + * @brief 打印提示符:统一使用\r\n换行,并且打印"> "于行首 */ - void processCommand(const QString &command, QTcpSocket *clientSocket) { - // 打印日志 - qDebug() << "Received command:" << command; - std::cout << "Received command: " << command.toStdString() << "\n"; - - // 以下为原先 onReadyRead() 中的 if / else if 处理逻辑 - // ------------------------------------------------------ - if (command == "help") { - QString helpText = "Available commands:\n"; - helpText += "TEST_NUM= - Set the TEST_NUM\n"; - helpText += "rc - Execute rocketmq_test_rc\n"; - helpText += "rt - Execute rocketmq_test_rt\n"; - helpText += "ud - Execute rocketmq_test_ud\n"; - helpText += "set - Execute rocketmq_test_set\n"; - helpText += "only - Execute rocketmq_test_only\n"; - helpText += "log - Execute rocketmq_test_log\n"; - helpText += "ledger - Execute ledger with optional terminal_id\n"; - helpText += "viewlog - View logs (ERROR, WARN, NORMAL, DEBUG)\n"; - helpText += "value - Execute value print with valuename : iedcount frontfun frontindex remtable log init\n"; - helpText += "exit - Exit the shell\n"; - helpText += "help - Show this help message\n"; - clientSocket->write(helpText.toUtf8()); - } - else if (command.startsWith("viewlog")) { - showinshellflag = true; - handleViewLogCommand(command, clientSocket); - } - // 设置多点模拟的个数 - else if (command.startsWith("TEST_NUM=")) { - bool ok; - int num = command.mid(9).toInt(&ok); // 获取等号后面的数字部分 - if (ok) { - setTestNum(num); // 更新 TEST_NUM - clientSocket->write("TEST_NUM updated\n"); - std::cout << "TEST_NUM updated\n"; - } else { - clientSocket->write("Invalid number\n"); - std::cout << "Invalid number\n"; - } - } - // 发送补招数据测试文本 - else if (command.startsWith("rc")) { - qDebug() << "Executing rocketmq_test_rc()"; - std::cout << "Executing rocketmq_test_rc()\n"; - rocketmq_test_rc(); // 调用 rc 函数 - clientSocket->write("Executed rocketmq_test_rc\n"); - } - // 发送实时数据测试文本 - else if (command.startsWith("rt")) { - qDebug() << "Executing rocketmq_test_rt()"; - std::cout << "Executing rocketmq_test_rt()\n"; - rocketmq_test_rt(); // 调用 rt 函数 - clientSocket->write("Executed rocketmq_test_rt\n"); - } - // 发送台账更新测试文本 - else if (command.startsWith("ud")) { - qDebug() << "Executing rocketmq_test_ud()"; - std::cout << "Executing rocketmq_test_ud()\n"; - rocketmq_test_ud(); // 调用 ud 函数 - clientSocket->write("Executed rocketmq_test_ud\n"); - } - // 发送进程控制测试文本 - else if (command.startsWith("set")) { - qDebug() << "Executing rocketmq_test_set()"; - std::cout << "Executing rocketmq_test_set()\n"; - rocketmq_test_set(); // 调用 set 函数 - clientSocket->write("Executed rocketmq_test_set\n"); - } - // 发送单连进程测试文本 - else if (command.startsWith("only")) { - qDebug() << "Executing rocketmq_test_only()"; - std::cout << "Executing rocketmq_test_only()\n"; - rocketmq_test_only(); // 调用 rocketmq_test_only 函数 - clientSocket->write("Executed rocketmq_test_only\n"); - } - // 发送实时日志测试文本 - else if (command.startsWith("log")) { - qDebug() << "Executing rocketmq_test_log()"; - std::cout << "Executing rocketmq_test_log()\n"; - rocketmq_test_log(); // 调用 log 函数 - clientSocket->write("Executed rocketmq_test_log\n"); - } - // 查看当前进程的台账 - else if (command.startsWith("ledger")) { - qDebug() << "Executing ledger()"; - std::cout << "Executing ledger()\n"; - - // 提取参数 - QStringList parts = command.split(" "); // 根据空格分割命令 - if (parts.size() > 1) { // 如果命令中包含参数(即 id号) - QString terminalId = parts[1]; - std::cout << "Calling ledger with terminal_id: " << terminalId.toStdString() << std::endl; - - ledger(terminalId.toStdString().c_str(), clientSocket); // 带参数调用 ledger - clientSocket->write("Executed ledger with terminal_id\n"); - } else { - std::cout << "Calling ledger without parameters\n"; - ledger(NULL, clientSocket); // 无参数调用 ledger - clientSocket->write("Executed ledger without parameters\n"); - } - } - // 查看当前进程的指定值 - else if (command.startsWith("value")) { - std::cout << "Executing value()" << std::endl; - - // 提取命令中的参数,获取变量名 - QStringList parts = command.split(" "); - if (parts.size() > 1) { - QString variableName = parts[1]; - std::cout << "Calling value() with variable name: " << variableName.toStdString() << std::endl; - - // 调用 value_print() 输出变量值 - value_print(variableName.toStdString().c_str(), clientSocket); - clientSocket->write("Executed value with variable name: " + variableName.toUtf8() + "\n"); - } else { - std::cout << "Calling value without parameters" << std::endl; - clientSocket->write("Please provide a variable name\n"); - } - } - // 处理 exit 命令 - else if (command == "exit") { - // 发送退出信息并关闭客户端连接 - clientSocket->write("Goodbye! Exiting shell...\n"); - clientSocket->flush(); - clientSocket->disconnectFromHost(); // 关闭连接 - clientSocket->waitForDisconnected(); // 确保连接断开 - return; - } - // 未知命令 - else { - clientSocket->write("Unknown command\n"); - } - - // 处理完命令后,回显一个新行和提示符 - clientSocket->write("> "); + void printPrompt(QTcpSocket *clientSocket) + { + //clientSocket->write("\r\n> "); + clientSocket->write("\r\x1B[K> "); clientSocket->flush(); } /** - * @brief 处理上箭头,从历史记录中调出上一条命令 + * @brief 执行一条命令(已被trimmed) + */ + void processCommand(const QString &cmd, QTcpSocket *clientSocket) { + qDebug() << "Received command:" << cmd; + std::cout << "Received command: " << cmd.toStdString() << "\n"; + + // 命令解析 + if (cmd == "help") { + QString helpText = "Available commands:\r\n"; + helpText += "TEST_NUM= - Set the TEST_NUM\r\n"; + helpText += "rc - Execute rocketmq_test_rc\r\n"; + helpText += "rt - Execute rocketmq_test_rt\r\n"; + helpText += "ud - Execute rocketmq_test_ud\r\n"; + helpText += "set - Execute rocketmq_test_set\r\n"; + helpText += "only - Execute rocketmq_test_only\r\n"; + helpText += "log - Execute rocketmq_test_log\r\n"; + helpText += "ledger - Execute ledger with optional terminal_id\r\n"; + helpText += "viewlog - View logs (ERROR, WARN, NORMAL, DEBUG)\r\n"; + helpText += "value - Execute value print with valuename\r\n"; + helpText += "exit - Exit the shell\r\n"; + helpText += "help - Show this help message\r\n"; + clientSocket->write("\r\x1B[K"); + clientSocket->write(helpText.toUtf8()); + } + else if (cmd.startsWith("viewlog")) { + showinshellflag = true; + handleViewLogCommand(cmd, clientSocket); + } + else if (cmd.startsWith("TEST_NUM=")) { + bool ok; + int num = cmd.mid(9).toInt(&ok); + if (ok) { + setTestNum(num); + clientSocket->write("\r\x1B[K"); + clientSocket->write("TEST_NUM updated\r\n"); + } else { + clientSocket->write("\r\x1B[K"); + clientSocket->write("Invalid number\r\n"); + } + } + else if (cmd.startsWith("rc")) { + rocketmq_test_rc(); + clientSocket->write("\r\x1B[K"); + clientSocket->write("Executed rocketmq_test_rc\r\n"); + } + else if (cmd.startsWith("rt")) { + rocketmq_test_rt(); + clientSocket->write("\r\x1B[K"); + clientSocket->write("Executed rocketmq_test_rt\r\n"); + } + else if (cmd.startsWith("ud")) { + rocketmq_test_ud(); + clientSocket->write("\r\x1B[K"); + clientSocket->write("Executed rocketmq_test_ud\r\n"); + } + else if (cmd.startsWith("set")) { + rocketmq_test_set(); + clientSocket->write("\r\x1B[K"); + clientSocket->write("Executed rocketmq_test_set\r\n"); + } + else if (cmd.startsWith("only")) { + rocketmq_test_only(); + clientSocket->write("\r\x1B[K"); + clientSocket->write("Executed rocketmq_test_only\r\n"); + } + else if (cmd.startsWith("log")) { + rocketmq_test_log(); + clientSocket->write("\r\x1B[K"); + clientSocket->write("Executed rocketmq_test_log\r\n"); + } + else if (cmd.startsWith("ledger")) { + QStringList parts = cmd.split(" "); + if (parts.size() > 1) { + QString terminalId = parts[1]; + ledger(terminalId.toStdString().c_str(), clientSocket); + clientSocket->write("\r\x1B[K"); + clientSocket->write("Executed ledger with terminal_id\r\n"); + } else { + ledger(NULL, clientSocket); + clientSocket->write("\r\x1B[K"); + clientSocket->write("Executed ledger without parameters\r\n"); + } + } + else if (cmd.startsWith("value")) { + QStringList parts = cmd.split(" "); + if (parts.size() > 1) { + QString variableName = parts[1]; + value_print(variableName.toStdString().c_str(), clientSocket); + clientSocket->write("\r\x1B[K"); + clientSocket->write("Executed value with variable name: " + variableName.toUtf8() + "\r\n"); + } else { + clientSocket->write("\r\x1B[K"); + clientSocket->write("Please provide a variable name\r\n"); + } + } + else if (cmd == "exit") { + clientSocket->write("\r\x1B[K"); + clientSocket->write("Goodbye! Exiting shell...\r\n"); + clientSocket->flush(); + clientSocket->disconnectFromHost(); + clientSocket->waitForDisconnected(); + return; + } + else { + clientSocket->write("\r\x1B[K> "); + clientSocket->write("Unknown command\r\n"); + clientSocket->flush(); + } + + // 命令处理结束后,打印提示符 + printPrompt(clientSocket); + } + + /** + * @brief 上箭头:历史命令回溯 */ void handleUpArrow(QTcpSocket *clientSocket) { if (!commandHistory.isEmpty() && historyIndex > 0) { historyIndex--; currentCommand = commandHistory[historyIndex]; - // **清空当前行** - clientSocket->write("\r"); // 移动光标到行首 - clientSocket->write(" "); // 用空格覆盖 - clientSocket->write("\r> "); // 重新打印提示符 - clientSocket->write(currentCommand.toUtf8()); // 回显历史命令 + // 清行:\r回到行首 + \x1B[K清除光标后文字 + clientSocket->write("\r\x1B[K> "); + clientSocket->write(currentCommand.toUtf8()); clientSocket->flush(); } } /** - * @brief 处理下箭头,从历史记录中调出下一条命令 + * @brief 下箭头:历史命令前进 */ void handleDownArrow(QTcpSocket *clientSocket) { if (!commandHistory.isEmpty() && historyIndex < commandHistory.size() - 1) { historyIndex++; currentCommand = commandHistory[historyIndex]; - // **清空当前行** - clientSocket->write("\r"); - clientSocket->write(" "); - clientSocket->write("\r> "); - clientSocket->write(currentCommand.toUtf8()); // 回显历史命令 + clientSocket->write("\r\x1B[K> "); + clientSocket->write(currentCommand.toUtf8()); clientSocket->flush(); } else if (historyIndex == commandHistory.size() - 1) { - // **如果已经是最后一条,再按下箭头,则清空当前输入** historyIndex = commandHistory.size(); currentCommand.clear(); - clientSocket->write("\r"); - clientSocket->write(" "); - clientSocket->write("\r> "); + clientSocket->write("\r\x1B[K> "); clientSocket->flush(); } } @@ -529,6 +561,10 @@ private: QList commandHistory; // 存储历史命令 int historyIndex; // 当前历史命令索引 QString currentCommand; // 当前正在输入的命令 + + // viewlog 相关 + bool stopViewLog; + QTcpSocket* activeClient; }; diff --git a/mms/mms_process.c b/mms/mms_process.c index 6e3e7c4..dd2c4da 100644 --- a/mms/mms_process.c +++ b/mms/mms_process.c @@ -1633,7 +1633,7 @@ void CheckNextNotConnectedChannel() connectlog_pgsql(ied_usr->terminal_code,convertMsToDateTimeString((int)sGetMsTime()),0);//0失败 //printf("check error88 !!!!!!!!!!!!!!\n"); } - printf( "reqCtrl->result == FAIL, Since StartConnecting %i 秒 ,channel IP %s:%d \n",secsSince,chnl_usr->ip_str,chnl_usr->chnl->port); + printf( "reqCtrl->result == FAIL, Since StartConnecting %i sec ,channel IP %s:%d \n",secsSince,chnl_usr->ip_str,chnl_usr->chnl->port); mvl_free_req_ctrl(chnl_usr->m_reqCtrl); chnl_usr->m_reqCtrl = NULL; chnl_usr->net_info->rem_vmd = NULL; diff --git a/pt61850netd_pqfe.pro b/pt61850netd_pqfe.pro index 68eb441..261b7df 100644 --- a/pt61850netd_pqfe.pro +++ b/pt61850netd_pqfe.pro @@ -14,6 +14,20 @@ DEFINES += _CRT_SECURE_NO_WARNINGS DEFINES += MMS_LITE LINUX=2 MOSI LEAN_T TP0_ENABLED DEFINES += CLIENT _DEBUG _REENTRANT _GNU_SOURCE _LARGEFILE64_SOURCE +# 娣诲姞 debug/release 缂栬瘧閫夐」閰嶇疆 +CONFIG(debug, debug|release) { + message("Building debug version with debug symbols") + # 寮哄埗鐢熸垚璋冭瘯淇℃伅骞剁鐢ㄤ紭鍖 + QMAKE_CFLAGS_DEBUG += -g -O0 + QMAKE_CXXFLAGS_DEBUG += -g -O0 + CONFIG += force_debug_info +} else { + message("Building release version") + # release 閫氬父寮鍚紭鍖 + QMAKE_CFLAGS_RELEASE += -O2 + QMAKE_CXXFLAGS_RELEASE += -O2 +} + win32 { DEFINES -= UNICODE DEFINES += _AFXDLL