#include"class_uart.h"#include<iostream>using namespace std;modbus_t* ctx = nullptr;Class_uart* Class_uart::handler = nullptr;Class_uart::Class_uart() {}intClass_uart::initUART(){ // 1. 创建 Modbus RTU 上下文 // 参数:串口设备路径,波特率,校验位,数据位,停止位 // 校验位:'N'=无校验,'E'=偶校验,'O'=奇校验 ctx = modbus_new_rtu("/dev/ttyAS3", 9600, 'N', 8, 1); if (ctx == nullptr) { std::cerr << "无法创建 Modbus RTU 上下文" << std::endl; return -1; } // 2. 设置从站地址(Slave Address = 01) int slave_id = 1; if (modbus_set_slave(ctx, slave_id) == -1) { std::cerr << "设置从站地址失败" << std::endl; modbus_free(ctx); return -1; } // 3. 连接 Modbus 设备 if (modbus_connect(ctx) == -1) { std::cerr << "连接 Modbus 设备失败: " << modbus_strerror(errno) << std::endl; modbus_free(ctx); return -1; } // 可选:开启调试输出,便于排查问题 // modbus_set_debug(ctx, TRUE); std::cout << "成功连接到 Modbus 从站设备,地址: " << slave_id << std::endl; return 1;}intClass_uart::readTH(uint16_t& uint16T,uint16_t& uint16H){ // 4. 读取输入寄存器(Input Register) // 起始地址: 0x0000,读取2个寄存器 uint16_t regTH_value[2] = {0}; // 存储1个寄存器的值(16位) // int rt = modbus_read_input_registers(ctx, 0x0000, 2, regTH_value);//0x04 int rt = modbus_read_registers(ctx, 0x0000, 2, regTH_value);//0x03 if (rt == -1) { std::cerr << "读取输入寄存器失败: " << modbus_strerror(errno) << std::endl; modbus_close(ctx); modbus_free(ctx); return -1; } uint16T = regTH_value[0]; uint16H = regTH_value[1]; // 5. 输出读取结果 std::cout << "读取成功!共读取 " << rt << " 个寄存器" << std::endl; std::cout << "寄存器地址 0x0000 的值: "<<regTH_value[0]<<"(0x"<<std::hex<<regTH_value[0]<< std::dec<<")"<< std::endl; std::cout << "寄存器地址 0x0000 的值: "<<regTH_value[1]<<"(0x"<<std::hex<<regTH_value[1]<< std::dec<<")"<< std::endl; return 1;}
#include"class_tcpserver.h"#include<iostream>#include<unistd.h>#include<sys/socket.h>#include<netinet/in.h>#include<arpa/inet.h>#include<fcntl.h>#include<string.h>#include<sys/epoll.h>#include<errno.h>#include"class_uart.h"using namespace std;Class_tcpserver* Class_tcpserver::handler = nullptr;Class_uart* uartInstance = Class_uart::getInstance ();Class_tcpserver::Class_tcpserver() { running_tcp_server = 1; tcpServerfd = -1; epoll_fd = -1;}intClass_tcpserver::initTcpServer(){ // 1. 创建监听 socket tcpServerfd = socket(AF_INET, SOCK_STREAM, 0); if (tcpServerfd < 0) { perror("socket"); return -1; } // 允许端口重用,避免 "Address already in use" int opt = 1; setsockopt(tcpServerfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); // 2. 绑定到 192.168.90.29:5270 struct sockaddr_in serverAddr; memset(&serverAddr, 0, sizeof(serverAddr)); serverAddr.sin_family = AF_INET; serverAddr.sin_port = htons(5270); if (inet_pton(AF_INET, "192.168.90.29", &serverAddr.sin_addr) <= 0) { perror(" inet_pton "); close(tcpServerfd); return -1; } if (bind(tcpServerfd, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) < 0) { perror(" bind "); close(tcpServerfd); return -1; } // 3. 开始监听 if (listen(tcpServerfd, 10) < 0) { perror(" listen "); close(tcpServerfd); return -1; } // 监听 socket 设为非阻塞(epoll必须) int flags = fcntl(tcpServerfd, F_GETFL, 0); fcntl(tcpServerfd, F_SETFL, flags | O_NONBLOCK); // 4. 创建 epoll 实例 epoll_fd = epoll_create1(0); if (epoll_fd < 0) { perror("epoll_create1"); close(tcpServerfd); return 1; } // 将监听 fd 加入 epoll,关注读事件 struct epoll_event ev; ev.events = EPOLLIN; ev.data.fd = tcpServerfd; if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, tcpServerfd, &ev) < 0) { perror("epoll_ctl add"); } return 1;}voidClass_tcpserver::RunTcpServer(){ std::cout << "Server listening on 192.168.90.29:5270" << std::endl; const int MAX_EVENTS = 64; struct epoll_event events[MAX_EVENTS]; static int timercount = 0; uint16_t uint16T; uint16_t uint16H; while (running_tcp_server > 0) { // epoll_wait 超时 1 毫秒 int nfds = epoll_wait(epoll_fd, events, MAX_EVENTS, 1); if (nfds < 0) { perror("epoll_wait"); break; } else if(nfds == 0) { timercount++; if(timercount > 990) { timercount = 0; uartInstance->readTH (uint16T,uint16H); // std::cout << "uint16T"<<uint16T<<endl; // std::cout << "uint16H"<<uint16H<<endl; int t1 = uint16T%100; int t2 = (uint16T/100); string str_t = "温度:"; str_t.append(std::to_string (t2)); str_t.append ("."); str_t.append (std::to_string (t1)); int h1 = uint16H%100; int h2 = (uint16H/100); string str_h = " , 湿度:"; str_h.append(std::to_string (h2)); str_h.append ("."); str_h.append (std::to_string (h1)); string message = ""; message.append (str_t); message.append (str_h); std::cout << message <<endl; for (auto it = clients.begin(); it != clients.end(); ) { const char* msg = message.data (); int n = send(it->fd, msg, strlen(msg), 0); if (n < 0) { // 发送出错(非 EAGAIN 则表示连接已异常) if (errno != EAGAIN && errno != EWOULDBLOCK) { std::cout << "Send error, disconnecting: " << it->ip << ":" << it->port << std::endl; // 连接关闭或出错,从 epoll 和 list 中移除 epoll_ctl(epoll_fd, EPOLL_CTL_DEL, it->fd, nullptr); close(it->fd); it = clients.erase(it); // 删除并获取下一个迭代器 } else { ++it; // 缓冲区满,下次再试 } } else { ++it; } } } } else { // 处理所有就绪事件 for (int i = 0; i < nfds; ++i) { int fd = events[i].data.fd; // 如果是监听 socket,接受新连接 if (fd == tcpServerfd) { struct sockaddr_in clientAddr; socklen_t addrLen = sizeof(clientAddr); int clientfd = accept(tcpServerfd, (struct sockaddr*)&clientAddr, &addrLen); if (clientfd < 0) { perror("accept"); continue; } char ipStr[INET_ADDRSTRLEN]; inet_ntop(AF_INET, &clientAddr.sin_addr, ipStr, sizeof(ipStr)); uint16_t port = ntohs(clientAddr.sin_port); int flags = fcntl(clientfd, F_GETFL, 0); fcntl(clientfd, F_SETFL, flags | O_NONBLOCK); // 将监听 fd 加入 epoll,关注读事件 struct epoll_event ev; ev.events = EPOLLIN; ev.data.fd = clientfd; if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, clientfd, &ev) < 0) { perror("epoll_ctl add"); } clients.push_back({clientfd, std::string(ipStr), port}); std::cout << "New client connected: " << ipStr << ":" << port << " (total: " << clients.size() << ")" << std::endl; } else { // 客户端 socket 可读 char buffer[1024]; int n = recv(fd, buffer, sizeof(buffer), 0); if (n <= 0) { // 连接关闭或出错,从 epoll 和 list 中移除 epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd, nullptr); close(fd); // 在 list 中查找并删除该 fd for (auto it = clients.begin(); it != clients.end(); ++it) { if (it->fd == fd) { std::cout << "Client disconnected: " << it->ip << ":" << it->port << std::endl; clients.erase(it); break; } } } else { // 收到数据,本例不处理,仅打印(可选) buffer[n] = '\n'; std::cout << "Received " << n << " bytes from " << fd <<" : "<< buffer <<std::endl; } } } } }}voidClass_tcpserver::stopTcpServer(){ running_tcp_server = -100; std::cout << "Server closing 192.168.90.29:5270" << std::endl; for (auto it = clients.begin(); it != clients.end(); ) { epoll_ctl(epoll_fd, EPOLL_CTL_DEL, it->fd, nullptr); close(it->fd); it = clients.erase(it); } close(tcpServerfd); close(epoll_fd); // 清理 std::cout << "清理完成" << std::endl;}