windows系统vtk-v9.1.0使用Qt5.15.2自带mingw810_64进行编译

在windows中使用mingw编译vtk存在不少问题, 测试了几个高于vtk-v9.1.0的版本都存在一些问题导致无法正常编译, 本文记录下编译过程 相关资源下载地址 cmake-3.31.4-windows-x86_64.msi vtk-v9.1.0 VTK编译 & 安装 前置操作: 将Qt5.15.2中的mingw810_64的bin目录添加到系统环境变量中,并重启操作系统, 如: C:\Qt\Tools\mingw810_64\bin 打开C:\Qt\Tools\mingw810_64\x86_64-w64-mingw32\include\winerror.h文件搜索ERROR_INCORRECT_SIZE __MSABI_LONG, 查看该定义下面是否有以下定义, 没有的话加上: #define ERROR_SYMLINK_CLASS_DISABLED 1463 #define ERROR_SYMLINK_NOT_SUPPORTED 1464 #define ERROR_XML_PARSE_ERROR 1465 #define ERROR_XMLDSIG_ERROR 1466 #define ERROR_RESTART_APPLICATION 1467 #define ERROR_WRONG_COMPARTMENT 1468 #define ERROR_AUTHIP_FAILURE 1469 #define ERROR_NO_NVRAM_RESOURCES 1470 下载并安装cmake 下载并解压vtk-v9.1.0 进入vtk-v9.1.0目录下创建build文件夹 打开cmake-gui对vtk-v9.1.0进行配置 设置源码和编译路径 点击Configure按钮, 选择MinGW Makefiles, 然后点击Finish 需要等待CMake进行一些配置, 然后会出现一些新的选项, 下面是一些我们要配置的选项, 先选中界面上的Advanced复选框: Name Value 描述 CMAKE_CXX_FLAGS -fcommon - CMAKE_C_FLAGS -fcommon - CMAKE_BUILD_TYPE Release 以Release的模式进行编译 CMAKE_INSTALL_PREFIX C:\Library\VTK 执行make install时的安装路径 VTK_GROUP_ENABLE_Qt YES 使能Qt选项 ...

January 25, 2025 · 1 min · 104 words · noxrick91

Qt使用Keepalive机制实现断线重连

QTcpSocket能够检测到Socket的连接与断开状态,并触发相关信号,我们只需要关联信号与槽就能够知道连接状态。 connect(&m_socket, &QTcpSocket::connected, this, &TcpClient::onConnected, Qt::QueuedConnection); connect(&m_socket, &QTcpSocket::disconnected, this, &TcpClient::onDisconnected, Qt::QueuedConnection); 还有一些特殊情况是无法触发QTcpSocket::disconnected信号,比如说:网线突然拔了、对端设备突然爆掉了等。这类情况由于对端socket未正常调用close()方法而导致的。 我们可以定义一个心跳包去定期检查对端的存活状态,这种做法在协议还未指定的初期是比较适合的,客户端与服务端制定一套心跳请求与应答机制来判断对端的存活状态。但是往往下位机的程序已经存在(开发者不愿意修改或增加现有协议),这时候如何能够在特殊情况下检测到网络断开呢? 主角登场:Keepalive机制 keepalive简介(摘自维基百科) 传输控制协议(TCP)存活包为可选特性,且默认关闭。存活包内没有数据。在以太网网络中,存活包的大小为最小长度的几帧(64字节)。协议中,还有三个与存活包相关的参数: 存活时长(英语:Keepalive time)即空闲时,两次传输存活包的持续时间。TCP存活包时长可手动配置,默认不少于2个小时。 存活间隔(英语:Keepalive interval)即未收到上个存活包时,两次连续传输存活包的时间间隔。 存活重试次数(英语:Keepalive retry)即在判断远程主机不可用前的发送存活包次数。当两个主机透过TCP/IP协议相连时,TCP存活包可用于判断连接是否可用,并按需中断。 多数支持TCP协议的主机也同时支持TCP存活包。每个主机按一定周期向其他主机发送TCP包来请求回应。若发送主机未收到特定主机的回应(ACK),则将从发送主机一侧中断连接。 若其他主机在连接关闭后发送TCP存活包,关闭连接的一方将发送RST包来表明旧连接已不可用。其他主机将关闭它一侧的连接以新建连接。 空闲的TCP连接通常会隔每45秒或60秒发送一次存活包。在未连续收到三次ACK包时,连接将中断。此行为因主机而异,如默认情况下的Windows主机将在7200000ms(2小时)后发送首个存活包,随后再以1000ms的间隔发送5个存活包。若任意存活包未收到回应,连接将被中断。 Qt开启Keepalive(Linux与Windows) #include "keepalive.h" #include <QObject> const int keepalive = 1; // 开启keepalive属性 const int keepidle = 5; // 如果连接在5秒内没有任何数据来往则进行探测 const int keepinterval = 3; // 探测时发包的时间间隔为3秒 const int keepcount = 3; // 尝试探测的次数, 如果第一次探测包就收到响应,则不在继续探测 #if defined (Q_OS_LINUX) || defined (Q_OS_MACOS) #include <sys/socket.h> #include <sys/types.h> #include <netinet/tcp.h> #include <netinet/in.h> // 开启TCP心跳检测机制 int enableKeepalive(int fd) { if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &keepalive, sizeof(keepalive)) < 0) return -1; if (setsockopt(fd, SOL_TCP, TCP_KEEPIDLE, &keepidle, sizeof(keepidle)) < 0) return -1; if (setsockopt(fd, SOL_TCP, TCP_KEEPINTVL, &keepinterval, sizeof(keepinterval)) < 0) return -1; if (setsockopt(fd, SOL_TCP, TCP_KEEPCNT, &keepcount, sizeof(keepcount)) < 0) return -1; return 0; } #elif defined (Q_OS_WIN) #include <winsock2.h> #define SIO_KEEPALIVE_VALS _WSAIOW(IOC_VENDOR,4) struct tcp_keepalive { unsigned long onoff; unsigned long keepalivetime; unsigned long keepaliveinterval; }; int enableKeepalive(int fd) { if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (char*)&keepalive, sizeof(keepalive)) < 0) return -1; struct tcp_keepalive in_keep_alive; memset(&in_keep_alive, 0, sizeof(in_keep_alive)); unsigned long ul_in_len = sizeof(struct tcp_keepalive); struct tcp_keepalive out_keep_alive; memset(&out_keep_alive, 0, sizeof(out_keep_alive)); unsigned long ul_out_len = sizeof(struct tcp_keepalive); unsigned long ul_bytes_return = 0; in_keep_alive.onoff = 1; // 打开keepalive in_keep_alive.keepaliveinterval = keepinterval * 1000; // 发送keepalive心跳时间间隔-单位为毫秒 in_keep_alive.keepalivetime = keepidle * 1000; // 多长时间没有报文开始发送keepalive心跳包-单位为毫秒 if (WSAIoctl(fd, SIO_KEEPALIVE_VALS, (LPVOID)&in_keep_alive, ul_in_len, (LPVOID)&out_keep_alive, ul_out_len, &ul_bytes_return, NULL, NULL) < 0) return -1; return 0; } #else int enableKeepalive(int fd) { Q_UNUSED(fd); return -1; } #endif Socket文件描述符的获取 QAbstractSocket::socketDescriptor() ,在socket连接成功后可使通过m_socket->socketDescriptor();获取到QTcpSocket的文件描述符(FD),失败时返回-1,这边获取到的fd可以提供给int enableKeepalive(int fd);作为参数用于启用keepalive。 ...

July 16, 2024 · 2 min · 319 words · noxrick91