【QT常用技术讲解】优化网络链接不上导致qt、qml界面卡顿的问题

前言

        qt、qml项目经常会涉及访问MySQL数据库、网络服务器,并且界面打开时的初始化过程就会涉及到链接Mysql、网络服务器获取数据,如果网络不通,卡个几十秒,会让用户觉得非常的不爽,本文从技术调研的角度讲解解决此类问题的socket编程方案。

调研场景一

目标:是否有成熟的第三方工具,可以通过后台命令行判断指定IP的某个端口是否在线。(其他文章分享有多线程启动第三方工具并获取结果的方法,不会导致界面卡顿)

经过调研,发现有两个工具初步满足需求:

nmap工具

格式:nmap -p [端口] [IP地址],如下所示

nmap -p 3306 192.168.1.123

如上效果图,内容较为详细,但不管端口是否在线,都花费5秒钟才能输出结果,比较影响界面的体验。

nc工具

格式:nc -zv [IP地址] [端口] -w 1            -w1是1秒钟超时

nc -zc 192.168.1.123 3306 -w1

如上效果图,加了超时参数-w1之后,确实是1秒中之内出结果,并且succeeded表示端口在线,但是当使用多线程获取此命令行返回的结果时,发现结果是空的,是在国产系统(统信UOS和麒麟kylin系统上进行的测试),然后在后台命令行进行重定向>1.txt,并且cat 1.txt时,发现输出结果也是空的,网上查资料说可能是按照的是特殊的版本,输出结果无法重定向(没有深究,因为可以调研socket编程来实现)。

socket设置超时

1、QT的QsqlDatabase

首先尝试了QsqlDatabase的超时设置方法setConnectOptions("CONNECT_TIMEOUT=1"),代码执行时提示无效。

2、原生socket的setsockopt

当无法链接上指定IP的端口时,3秒才返回,接收数据被阻塞了。

#include <iostream>
#include <cstring>
#include <cstdlib>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <ctime>
#define qint64 std::time_tqint64 getcurtime(){// 获取当前时间戳(秒级)std::time_t timestamp = std::time(nullptr);return timestamp;
}bool checkPortOpen(const std::string& ip, int port, int timeout = 1) {qint64 bgtime=getcurtime();// 创建一个socketint sock = socket(AF_INET, SOCK_STREAM, 0);if (sock < 0) {std::cerr << "Socket creation failed!" << std::endl;return false;}// 设置超时参数struct timeval tv;tv.tv_sec = timeout; // 超时1秒tv.tv_usec = 0;setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof(tv));// 设置目标地址struct sockaddr_in serverAddr;serverAddr.sin_family = AF_INET;serverAddr.sin_port = htons(port);serverAddr.sin_addr.s_addr = inet_addr(ip.c_str());// 尝试连接指定的IP和端口int result = connect(sock, (struct sockaddr*)&serverAddr, sizeof(serverAddr));if (result == -1) {qint64 endtime=getcurtime();std::cout << " checksqlonline use time:" << endtime-bgtime << std::endl;close(sock); // 连接失败,关闭socketreturn false;}qint64 endtime=getcurtime();std::cout << " checksqlonline use time:" << endtime-bgtime << std::endl;close(sock); // 连接成功,关闭socketreturn true;
}int main(int argc, char **argv) {if (argc==1){printf("请传入参数:IP");return -1;}std::string ip = argv[1];  // 替换为你要检测的IPint port = 3306;                    // MySQL的默认端口3306if (checkPortOpen(ip, port)) {std::cout << "Port " << port << " on IP " << ip << " is open!" << std::endl;} else {std::cout << "Port " << port << " on IP " << ip << " is closed!" << std::endl;}return 0;
}

3、select异步socket

使用了异步模式,1秒以内返回,达到了优化的效果。

#include <iostream>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/select.h>
#include <netinet/in.h>
#include <cstring>
#include <ctime>
#define qint64 std::time_tqint64 getcurtime(){// 获取当前时间戳(秒级)std::time_t timestamp = std::time(nullptr);return timestamp;
}bool checkPortOpen(const std::string& ip, int port, int timeout_sec = 1) {qint64 bgtime=getcurtime();int sockfd = socket(AF_INET, SOCK_STREAM, 0);if (sockfd < 0) {std::cerr << "Error creating socket." << std::endl;return false;}// Set socket to non-blocking modefcntl(sockfd, F_SETFL, O_NONBLOCK);struct sockaddr_in server_addr;memset(&server_addr, 0, sizeof(server_addr));server_addr.sin_family = AF_INET;server_addr.sin_port = htons(port);inet_pton(AF_INET, ip.c_str(), &server_addr.sin_addr);// Start connecting to the server (this will be non-blocking)int connect_result = connect(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr));// Check if the connection was successful or pendingif (connect_result < 0) {if (errno != EINPROGRESS) {std::cerr << "Connection error: " << strerror(errno) << std::endl;close(sockfd);return false;}}// Use select() to set a timeout for the connectionfd_set writefds;FD_ZERO(&writefds);FD_SET(sockfd, &writefds);struct timeval timeout;timeout.tv_sec = timeout_sec;timeout.tv_usec = 0;int select_result = select(sockfd + 1, nullptr, &writefds, nullptr, &timeout);if (select_result > 0) {// Check if the socket is writable (connection succeeded)int so_error;socklen_t len = sizeof(so_error);getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &so_error, &len);if (so_error == 0) {// Port is openqint64 endtime=getcurtime();std::cout << " checksqlonline use time:" << endtime-bgtime << std::endl;close(sockfd);return true;}}qint64 endtime=getcurtime();std::cout << " checksqlonline use time:" << endtime-bgtime << std::endl;// If select result is <= 0, either timed out or failed to connectclose(sockfd);return false;
}int main(int argc, char **argv) {if (argc==1){printf("请传入参数:IP");return -1;}std::string ip = argv[1];  // 替换为你要检测的IPint port = 3306;                    // MySQL的默认端口3306if (checkPortOpen(ip, port)) {std::cout << "Port " << port << " on IP " << ip << " is open!" << std::endl;} else {std::cout << "Port " << port << " on IP " << ip << " is closed!" << std::endl;}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/471223.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于OpenCV的自制Python访客识别程序

这是我用Pyqt5&#xff0c;基于OpenCV做的一个Python访客识别程序&#xff0c;它具体包括如下5个功能&#xff1a; 1、选择媒体菜单&#xff0c;可以打开本地摄像头&#xff1b;如果知道rtsp地址&#xff0c;则可以直接访问局域网内的网络串流。 2、选择播放菜单&#xff0c;…

SQL集合运算

集合论是SQL语言的根基。 1 集合运算 注意事项&#xff1a; 1&#xff09;SQL能操作具有重复行的集合&#xff0c;可以通过可选项ALL来支持。 如果直接使用UNION或INTERSECT&#xff0c;结果里不会出现重复的行。如果想在结果里留下重复行&#xff0c;可以加上可选项ALL。写…

Gartner发布安全平台创新洞察:安全平台需具备的11项常见服务

安全和风险管理领导者的任务是管理多个安全供应商和复杂的基础设施堆栈。本研究提供了有关安全平台优势和风险的见解&#xff0c;并提供了为组织选择合适平台的建议。 主要发现 自适应和行为安全防御需要跨安全基础设施组件进行更多的协调&#xff0c;而目前孤立的异构供应商架…

基于海思soc的智能产品开发(两个图像处理来源)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 对于图像&#xff0c;大家能够想到的一般就是sensor&#xff0c;也就是摄像头。其实对于图像来说&#xff0c;还有另外一个来源&#xff0c;那就是…

如何使用 Web Scraper API 高效采集 Facebook 用户帖子信息

目录 前言一、什么是Web Scraper API二、Web Scraper API 的优势&#xff1a;三、Web Scraper API 适用场景四、实践案例目标需求视频讲解1、选择Web Scraper API2、登录注册3、进入用户控制面板4、选择API5、触发数据收集 API6、获取爬虫结果7、分析爬虫结果&#xff08;1&…

微信小程序中使用离线版阿里云矢量图标

前言 阿里矢量图库提供的在线链接服务仅供平台体验和调试使用&#xff0c;平台不承诺服务的稳定性&#xff0c;企业客户需下载字体包自行发布使用并做好备份。 1.下载图标 将阿里矢量图库的图标先下载下来 解压如下 2.转换格式 贴一个地址用于转换格式&#xff1a;Onlin…

Ubuntu 的 ROS 操作系统安装与测试

引言 机器人操作系统&#xff08;ROS, Robot Operating System&#xff09;是一个用于开发机器人应用的开源框架&#xff0c;它提供了一系列功能丰富的库和工具&#xff0c;能够帮助开发者构建和控制机器人。 当前&#xff0c;ROS1的最新版本为Noetic Ninjemys&#xff0c;专为…

封装一个省市区的筛选组件

筛选功能&#xff1a;只能单选&#xff08;如需多选需要添加show-checkbox多选框属性&#xff09;&#xff0c;选中省传递省的ID&#xff0c;选中市传递省、市的ID&#xff0c; 选中区传递省市区的ID 父组件&#xff1a; <el-form-item><div style"width: 240px;…

python制作一个简单的端口扫描器,用于检测目标主机上指定端口的开放状态

import argparse # 用于解析命令行参数 from socket import * # 导入 socket 库的所有内容&#xff0c;用于网络通信 from threading import * # 导入 threading 库的所有内容&#xff0c;用于多线程操作 # 创建一个信号量&#xff0c;初始值为 1&#xff0c;用于线程同步&…

OceanStor Pacific系列 8.1.0 功能架构

功能架构 华为OceanStor Pacific系列提供基于三层的分布式存储架构&#xff0c;融合分布式文件、对象、大数据和块多个服务形态&#xff0c;支持文件、对象、大数据服务部署在一个集群&#xff0c;并统一管理。 华为OceanStor Pacific系列整体功能架构由存储接口层、存储服务…

Flink1.19编译并Standalone模式本地运行

1.首先下载源码 2.本地运行 新建local_conf和local_lib文件夹&#xff0c;并且将编译后的文件放入对应的目录 2.1 启动前参数配置 2.1.2 StandaloneSessionClusterEntrypoint启动参数修改 2.1.3 TaskManagerRunner启动参数修改 和StandaloneSessionClusterEntrypoint一样修改…

高效稳定!新加坡服务器托管方案助力企业全球化布局

在全球化的商业环境中&#xff0c;企业对于高效、稳定的服务器托管方案的需求日益迫切。作为亚洲的服务器托管中心&#xff0c;新加坡凭借其独特的地理位置、稳定的政治环境、先进的科技设施以及开放的市场政策&#xff0c;为企业提供了理想的服务器托管解决方案&#xff0c;助…

JavaWeb后端开发知识储备1

目录 1.DTO/VO/PO 2.MVC架构/微服务架构 3.JWT令牌流程 4.ThreadLocal 5.接口路径/路径参数 1.DTO/VO/PO 1.1 DTO DTO 即 Data Transfer Object—— 数据传输对象&#xff0c;是用于传输数据的对象&#xff0c;通常在服务层与表现层之间传递数据&#xff0c;DTO 通常用于…

StructuredStreaming (一)

一、sparkStreaming的不足 1.基于微批,延迟高不能做到真正的实时 2.DStream基于RDD,不直接支持SQL 3.流批处理的API应用层不统一,(流用的DStream-底层是RDD,批用的DF/DS/RDD) 4.不支持EventTime事件时间&#xff08;一般流处理都会有两个时间&#xff1a;事件发生的事件&am…

信号-3-信号处理

main 信号捕捉的操作 sigaction struct sigaction OS不允许信号处理方法进行嵌套&#xff1a;某一个信号正在被处理时&#xff0c;OS会自动block改信号&#xff0c;之后会自动恢复 同理&#xff0c;sigaction.sa_mask 为捕捉指定信号后临时屏蔽的表 pending什么时候清零&…

软件工程师简历(精选篇)

【#软件工程师简历#】 一份专业而精准的软件工程师简历&#xff0c;不仅能够全面展示技术实力和项目经验&#xff0c;更是赢得理想工作机会的重要敲门砖。那么&#xff0c;如何撰写一份令人印象深刻的软件工程师简历呢&#xff1f;以下是幻主简历整理的软件工程师简历&#xf…

基于springboot的汽车租赁管理系统的设计与实现

项目描述 临近学期结束&#xff0c;还是毕业设计&#xff0c;你还在做java程序网络编程&#xff0c;期末作业&#xff0c;老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。这里根据疫情当下&#xff0c;你想解决的问…

vscode远程连接服务器并启用tmux挂载进程

使用vscode连接远程服务器&#xff0c;有时候由于主机问题&#xff0c;比如中断&#xff0c;断网&#xff0c;超时&#xff0c;重启&#xff0c;关机等等情况&#xff0c;导致进程中断&#xff0c;如果是一个长时间的进程&#xff0c;会很麻烦&#xff0c;毕竟不能长时间一直盯…

设计模式之装饰器模式(SSO单点登录功能扩展,增加拦截用户访问方法范围场景)

前言&#xff1a; 两个本想描述一样的意思的词&#xff0c;只因一字只差就让人觉得一个是好牛&#xff0c;一个好搞笑。往往我们去开发编程写代码时也经常将一些不恰当的用法用于业务需求实现中&#xff0c;但却不能意识到。一方面是由于编码不多缺少较大型项目的实践&#xff…

鸿蒙HarmonyOS 地图不显示解决方案

基于地图的开发准备已完成的情况下&#xff0c;地图还不显式的问题 首先要获取设备uuid 获取设备uuid 安装DevEco Studio的路径下 有集成好的hdc工具 E:\install_tools\DevEco Studio\sdk\default\openharmony\toolchains 这个路径下打开cmd运行 进入“设置 > 关于手机…