From 90a1dc8b52ba98a1a4fcbbaf556982001c1a0ae7 Mon Sep 17 00:00:00 2001 From: huyizhong Date: Mon, 8 Jul 2024 10:02:35 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A7=A3=E5=86=B3TCP=E8=BF=9E=E6=8E=A5?= =?UTF-8?q?=E4=B8=AD=E6=96=AD=E5=90=8E=EF=BC=8C=E6=96=B0=E7=9A=84=E8=BF=9E?= =?UTF-8?q?=E6=8E=A5=E4=B8=8D=E8=83=BD=E8=BF=9E=E6=8E=A5=E8=BF=9B=E6=9D=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/iedModbus_mgr/common.cpp | 8 +- src/iedModbus_mgr/database/database.cpp | 14 +-- src/iedModbus_mgr/iedModbus_mgr.cpp | 2 +- src/iedModbus_mgr/yspConfig.ini | 6 +- src/iedModbus_mgr/ysp_modbus_slave.cpp | 124 +++++++++++++++++++++++- 5 files changed, 136 insertions(+), 18 deletions(-) diff --git a/src/iedModbus_mgr/common.cpp b/src/iedModbus_mgr/common.cpp index 68d9c7a..d4a209a 100644 --- a/src/iedModbus_mgr/common.cpp +++ b/src/iedModbus_mgr/common.cpp @@ -25,7 +25,7 @@ using namespace std; #define DELAY_RUN(min) MIN_SLEEP_TIME(min) //监测周期 -static int pro_delay_min = DELAY_MIN_DEFAULT; +int pro_delay_min = DELAY_MIN_DEFAULT; //unsigned char 数组转16进制输出 void xUnsigned_char_hex_out(const char *msg, unsigned char* src, int start, int end) @@ -247,13 +247,13 @@ int xGet_config_from_configFile() const char* process_delay_min = ini_get(ini_ctl, "PROCESS", "DELAY_RUN_MIN"); if (process_delay_min) { pro_delay_min = atoi(process_delay_min); - printf("delay para %s min\n", process_delay_min); - printf("delay para: %d min\n", pro_delay_min); + //printf("delay para %s sec\n", process_delay_min); + printf("delay para: %d sec\n", pro_delay_min*10); } else { pro_delay_min = DELAY_MIN_DEFAULT; printf("DELAY_RUN_MIN is null,use default\n"); - printf("delay para: %d min\n", pro_delay_min); + printf("delay para: %d sec\n", pro_delay_min*10); } ini_free(ini_ctl); diff --git a/src/iedModbus_mgr/database/database.cpp b/src/iedModbus_mgr/database/database.cpp index e60bd63..b2acbf6 100644 --- a/src/iedModbus_mgr/database/database.cpp +++ b/src/iedModbus_mgr/database/database.cpp @@ -336,13 +336,13 @@ int fill_ysp_data(ysp_modbus_regs_t * ysp_data) for (i = 0; i < sizeof(ysp_modbus_regs_t) / 2; i++) { ptr[i] = 0x0000 + i; } - ysp_data->H2 =67.87; - ysp_data->CO = 102; - ysp_data->CO2 =65; - ysp_data->CH4 = 67.87; - ysp_data->C2H2 = 67.87; - ysp_data->C2H4 = 67.87; - ysp_data->C2H6 = 67.87; + ysp_data->H2 =1890.6; + ysp_data->CO = 4306.6; + ysp_data->CO2 =12000; + ysp_data->CH4 = 800; + ysp_data->C2H2 = 900; + ysp_data->C2H4 = 850.9; + ysp_data->C2H6 = 666.6; ysp_data->Total = 67.87; ysp_data->Water = 67.87; ysp_data->time_H32 = 0x11223344; diff --git a/src/iedModbus_mgr/iedModbus_mgr.cpp b/src/iedModbus_mgr/iedModbus_mgr.cpp index 5edca1d..1089e43 100644 --- a/src/iedModbus_mgr/iedModbus_mgr.cpp +++ b/src/iedModbus_mgr/iedModbus_mgr.cpp @@ -29,7 +29,7 @@ int main(int argc, char** argv) xProcess_unique(); - std::cout << "RUN YSP MONITOR APP! V1.12-x86\n"; + std::cout << "RUN YSP MONITOR APP! V1.13-x86\n"; #if 1 //com_test 鐢ㄦ潵寮鍙戞祴璇 鍙戝竷鏃朵笉璧蜂綔鐢 if (argc > 1) { diff --git a/src/iedModbus_mgr/yspConfig.ini b/src/iedModbus_mgr/yspConfig.ini index 499dd13..b5f414a 100644 --- a/src/iedModbus_mgr/yspConfig.ini +++ b/src/iedModbus_mgr/yspConfig.ini @@ -18,5 +18,9 @@ C2H4_alert=1 C2H6_alert=1 [MONITOR] -GAS_MONITOR_PERIOD = 33 +GAS_MONITOR_PERIOD = 1 + +[PROCESS] +DELAY_RUN_MIN = 30 + diff --git a/src/iedModbus_mgr/ysp_modbus_slave.cpp b/src/iedModbus_mgr/ysp_modbus_slave.cpp index 59ea2b4..8062e59 100644 --- a/src/iedModbus_mgr/ysp_modbus_slave.cpp +++ b/src/iedModbus_mgr/ysp_modbus_slave.cpp @@ -4,6 +4,7 @@ #include "database/database.h" # include # include +#include using namespace std; #define REG_ADDR (header_length+1) @@ -19,7 +20,7 @@ using namespace std; char slave_ip_addr[20] = { 0 }; //modbus slave tcp ip地址 unsigned short slave_tcp_port = TCP_PORT; //modbus slave tcp port端口号 - +extern int pro_delay_min; ysp_modbus_regs_t ysp_modbus_data; slave_add_t salve_addr = {0}; @@ -66,6 +67,86 @@ void xSet_slave_port(const char* tcp_port) printf("SLAVE_PORT is null,use default\n"); } } + +//创建 TCP Server socket +BYTE CreateTcpServerSock(int *LiSock, DWORD NetPort) +{ + int i, tmp, ret, retval; + + int len; + struct sockaddr_in addr; + u_long largp = 1L; //非阻塞模式 + char tmp_buf[256]; + + if (-1 < *LiSock) + return *LiSock; + + if (NetPort == 0) + return -1; + + *LiSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); + + if (*LiSock < 0) + { + *LiSock = -1; + return -1; + } + + // 将socket设置为非阻塞模式 + retval = ioctlsocket(*LiSock, FIONBIO, (u_long FAR*)&largp); + if (SOCKET_ERROR == retval) + { + // retval = WSAGetLastError(); + // sprintf(tmp_buf, "ioctlsocket设置非阻塞模式错误, SocketError=%d, SocketId = %d", retval, *LiSock); + // DebugPrint(tmp_buf); + closesocket(*LiSock); + *LiSock = -1; + return -1; + } + ///设置socket的输入输出缓冲区大小 + tmp = MODBUS_TCP_MAX_ADU_LENGTH; + setsockopt(*LiSock, SOL_SOCKET, SO_RCVBUF, (char*)&tmp, sizeof(tmp)); + tmp = MODBUS_TCP_MAX_ADU_LENGTH; + setsockopt(*LiSock, SOL_SOCKET, SO_SNDBUF, (char*)&tmp, sizeof(tmp)); + + len = 4; + tmp_buf[0] = 1; + + tmp = setsockopt(*LiSock, SOL_SOCKET, SO_KEEPALIVE, tmp_buf, len); + tmp = getsockopt(*LiSock, SOL_SOCKET, SO_KEEPALIVE, tmp_buf, &len); + tmp = 1; + // setsockopt(*LiSock, SOL_SOCKET, SO_KEEPALIVE, (char*)&tmp, sizeof(tmp)); + setsockopt(*LiSock, SOL_SOCKET, SO_REUSEADDR, (char*)&tmp, sizeof(tmp)); + //set_keepalive(*LiSock, keep_alive, keep_idle, keep_interval, keep_count); + + //让TCP接收所有连线 + memset((char*)&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(NetPort); + addr.sin_addr.s_addr = htonl(INADDR_ANY); + + //printf("TIP_(%04d): Port = %d, NetCommIpAddr(%08x), addr.sin_addr.s_addr(%08x)\n", getpid(), commid+1, *NetCommIpAddr, addr.sin_addr.s_addr); + if (bind(*LiSock, (struct sockaddr *)&addr, sizeof(addr)) < 0) + { + //printf("errno = %d\n", errno); + //close(*LiSock); + closesocket(*LiSock); + *LiSock = -1; + return -1; + } + //printf("succeed!\n"); + + ret = listen(*LiSock, 4); + if (ret < 0) + { + //close(*LiSock); + closesocket(*LiSock); + *LiSock = -1; + return -1; + } + return *LiSock; +} + DWORD WINAPI xModbus_msg_ThreadProc(LPVOID lp) { char* com = (char*)lp; CHAR rcv_buf[1024] = { 0 }; @@ -85,12 +166,13 @@ DWORD WINAPI xModbus_msg_ThreadProc(LPVOID lp) { struct sockaddr_in addr; socklen_t addrlen; //struct tcp_info info; + time_t ictime, recvtime; /* 一次只接受一个主机master连接 即 accept 只接受一个客户端连接,该连接错误退出后,重新走到这里来accept */ - + if (use_backend == TCP) { ctx = modbus_new_tcp(slave_ip_addr, slave_tcp_port); //modbus_set_slave(ctx, SERVER_ID); @@ -115,6 +197,7 @@ DWORD WINAPI xModbus_msg_ThreadProc(LPVOID lp) { modbus_free(ctx); return -1; } + for(;;){ if (use_backend == TCP) { if (s < 0) { @@ -165,9 +248,11 @@ DWORD WINAPI xModbus_msg_ThreadProc(LPVOID lp) { else if (use_backend == TCP_PI) { modbus_tcp_pi_accept(ctx, &s); } + ictime = time(NULL); + recvtime = ictime; std::cout << "modbus receive loop\n" << std::endl; for (;;) {//循环接受消息 -#if 1 +#if 0 if (s < 0) break; FD_ZERO(&fdset_ro); @@ -188,8 +273,9 @@ DWORD WINAPI xModbus_msg_ThreadProc(LPVOID lp) { s = -1; break; } + else if (FD_ISSET(s, &fdset_ro))// accept(*s, (struct sockaddr *) &addr, &addrlen); -#endif + { //std::cout << std::endl << "second accept wait connect (hold)\n" << std::endl; extrasock = accept(s, (struct sockaddr *) &addr, &addrlen); @@ -207,7 +293,7 @@ DWORD WINAPI xModbus_msg_ThreadProc(LPVOID lp) { } } } - +#endif if (NULL == ctx) return 0; if (0 > sockt) @@ -218,6 +304,15 @@ DWORD WINAPI xModbus_msg_ThreadProc(LPVOID lp) { FD_SET(sockt, &fdset_ro); FD_SET(sockt, &fdset_wr); FD_SET(sockt, &fdset_ex); + ictime = time(NULL); + if (ictime - recvtime > pro_delay_min*10) + { + closesocket(sockt); + sockt = -1; + printf("TCP connection timeout of% d seconds, no valid data received", ictime - recvtime); + recvtime = ictime; + break; + } memset((char*)&timeout, 0, sizeof(struct timeval)); if (select(sockt + 1, &fdset_ro, &fdset_wr, &fdset_ex, &timeout) < 1) { @@ -231,6 +326,21 @@ DWORD WINAPI xModbus_msg_ThreadProc(LPVOID lp) { sockt = -1; break; } +#if 1 + if (FD_ISSET(sockt, &fdset_wr)) + { + int ierrlen, ierr; + + ierrlen = sizeof(ierr); + rc = getsockopt(sockt, SOL_SOCKET, SO_ERROR, (char *)&ierr, &ierrlen); + if (SOCKET_ERROR == rc) + { + closesocket(sockt); + sockt = -1; + break; + } + } +#endif if (FD_ISSET(sockt, &fdset_ro)) // 可读 { do { @@ -268,6 +378,7 @@ DWORD WINAPI xModbus_msg_ThreadProc(LPVOID lp) { { //int len = sizeof(info); //getsockopt(sockt, IPPROTO_TCP, TCP_INFO, &info, (socklen t *)&len);if (info.tcpi state == TCP CLOSE WAIT && info.tcpi state != TCP ESTABLISHED) +#if 0 rc = recv(sockt, rcv_buf, 1,0); if (rc <= 0) { @@ -278,9 +389,12 @@ DWORD WINAPI xModbus_msg_ThreadProc(LPVOID lp) { printf("Client TCP may unexpectedly interrupt!\n"); } } +#endif + Sleep(5); continue; } + recvtime = time(NULL); std::cout << "modbus new msg\n" << std::endl; switch (query[header_length]) {