【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.mzph.cn/diannao/60589.shtml

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

相关文章

编程之路,从0开始:知识补充篇

Hello大家好&#xff0c;很高兴我们又见面了&#xff01; 给生活添点passion&#xff0c;开始今天的编程之路&#xff01; 这一篇我们来补充一下在之前篇目没讲到的知识&#xff0c;并结合一些码友的私信提问和我在编程中遇到的问题&#xff0c;做一些易错点或易混点的讲解。 …

C语言中,让人又爱又恨的字符串编码

引言 在C语言的世界里&#xff0c;字符串编码是一个让人既爱又恨的话题。 所有的打印信息&#xff0c;都是以字符串输出的。但是&#xff0c;大家在编码的时候&#xff0c;经常会遇到一些情况&#xff0c;稍不注意&#xff0c;就会导致显示出乱码&#xff0c;到了客户那里&…

nginx openresty lua-resty-http 使用的一些问题记录

需求背景 需求是使用 nginx 做一个 https 服务的代理 nginx 收到 http 请求后&#xff0c;需要修改 body 中的某些参数值&#xff0c;然后将修改后的数据发送到目标服务器&#xff08;https&#xff09; 本来以为很简单的需求&#xff0c;结果中间出现了不少岔子&#xff0c;这…

vue2+ element ui 集成pdfjs-dist

目录 1. 下载Pdf.js1.1 下载1.2 修改配置1.2.1 将pdfjs-3.8.162-dist复制到项目中1.2.2 解决跨域问题1.2.3 将pdf.worker.js文件复制到public目录下1.2.4 安装 pdfjs-dist1.2.5 前端vue代码(示例) 3. 参考资料 1. 下载Pdf.js 1.1 下载 下载链接&#xff08;官方&#xff09;需…

「Mac玩转仓颉内测版2」入门篇2 - 编写第一个Cangjie程序

本篇详细介绍在Mac系统上创建首个Cangjie项目并编写、运行第一个Cangjie程序的全过程。内容涵盖项目创建、代码编写、程序运行与调试&#xff0c;以及代码修改后的重新运行。通过本篇&#xff0c;掌握Cangjie项目的基本操作&#xff0c;进一步巩固开发环境的配置&#xff0c;迈…

接单渠道,程序员看这篇就够了。

接单、兼职&#xff0c;有团队没单子&#xff1f;僧多粥少&#xff0c;苦矣。 很多程序员&#xff0c;有时间、有技术&#xff0c;有steam&#xff08;咳咳&#xff0c;不对&#xff0c;是team&#xff09;。但是&#xff0c;可能还是挣不到什么钱&#xff0c;何也&#xff1f…

CSS:导航栏三角箭头

用CSS实现导航流程图的样式。可根据自己的需求进行修改&#xff0c;代码精略的写了一下。 注&#xff1a;场景一和场景二在分辨率比较低的情况下会有一个1px的缝隙不太优雅&#xff0c;自行处理。有个方法是直接在每个外面包一个DIV&#xff0c;用动态样式设置底色。 场景一、…

Qt_day4_Qt_UI设计

目录 Qt_UI设计 1. Designer 设计师&#xff08;掌握&#xff09; 2. Layout 布局&#xff08;重点&#xff09; 2.1 基本使用 2.2 高级用法 2.3 代码布局&#xff08;了解&#xff09; 3. Designer与C的关系&#xff08;熟悉&#xff09; 4. 基本组件&#xff08;掌握…

数据结构的时间复杂度和空间复杂度

目录 时间复杂度 空间复杂度 时间复杂度 基本操作的执行次数&#xff0c;为时间复杂度。 我们使用大O的渐进表示法来表示时间复杂度。 怎么使用&#xff1f; 先看例子&#xff1a; 在这个例子中&#xff0c; 基本操作为变量 count 的 加加 操作&#xff0c;并且&#xff0c;执行…

【Chapter 3】Machine Learning Classification Case_Prediction of diabetes-XGBoost

文章目录 1、XGBoost Algorithm2、Comparison of algorithm implementation between Python code and Sentosa_DSML community edition(1) Data reading and statistical analysis(2)Data preprocessing(3)Model Training and Evaluation(4)Model visualization 3、summarize 1…

Rust Struct 属性初始化

结构体是用户定义的数据类型&#xff0c;其中包含定义特定实例的字段。结构有助于实现更容易理解的抽象概念。本文介绍几种初始化结构体对象的方法&#xff0c;包括常规方法、Default特征、第三方包实现以及构建器模式。 Struct声明与初始化 struct Employee {id: i32,name: …

AI大模型微调:Qwen2大模型微调入门实战(完整代码)

简介&#xff1a; 该教程介绍了如何使用Qwen2&#xff0c;一个由阿里云通义实验室研发的开源大语言模型&#xff0c;进行指令微调以实现文本分类。微调是通过在&#xff08;指令&#xff0c;输出&#xff09;数据集上训练来改善LLMs理解人类指令的能力。教程中&#xff0c;使用…

基于Python+Django+Vue3+MySQL实现的前后端分类的商场车辆管理系统

项目名称&#xff1a;基于PythonDjangoVue3MySQL实现的前后端分离商场车辆管理系统 技术栈 开发工具&#xff1a;PyCharm、Visual Studio Code (VSCode)运行环境&#xff1a;Python 3.10、MySQL 8.0、Node.js 18技术框架&#xff1a;Django 5、Vue 3.4、Ant-Design-Vue 4.12 …

C++初阶:类和对象(上)

1. 类的定义 1.1 类的定义格式 class为定义类的关键字&#xff0c;Stack为类的名字&#xff0c;{ } 中为类的主体&#xff0c;注意类定义结束后的分号不能省略。类体中的内容为类的成员&#xff1a;类中的变量称为类的属性或成员变量&#xff1b;类中的函数称为类的方法或成员…

ctfshow DSBCTF web部分wp

ctfshow 单身杯 web部分wp web 签到好玩的PHP 源码&#xff1a; <?php error_reporting(0); highlight_file(__FILE__);class ctfshow {private $d ;private $s ;private $b ;private $ctf ;public function __destruct() {$this->d (string)$this->d;$this…

【分布式】万字图文解析——深入七大分布式事务解决方案

分布式事务 分布式事务是指跨多个独立服务或系统的事务管理&#xff0c;以确保这些服务中的数据变更要么全部成功&#xff0c;要么全部回滚&#xff0c;从而保证数据的一致性。在微服务架构和分布式系统中&#xff0c;由于业务逻辑往往会跨多个服务&#xff0c;传统的单体事务…

边缘计算在智能物流中的应用

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 边缘计算在智能物流中的应用 边缘计算在智能物流中的应用 边缘计算在智能物流中的应用 引言 边缘计算概述 定义与原理 发展历程 …

Spring Boot框架:电商开发的新趋势

5 系统实现 系统实现部分就是将系统分析&#xff0c;系统设计部分的内容通过编码进行功能实现&#xff0c;以一个实际应用系统的形式展示系统分析与系统设计的结果。前面提到的系统分析&#xff0c;系统设计最主要还是进行功能&#xff0c;系统操作逻辑的设计&#xff0c;也包括…

本地源配置 以及ssh 和 nfs

安装软件的三种方式 apt 仓库 在/etc/apt/sources.list文件下 在线源 离线包 修改离线包 挂载并更新 ssh远程管理 sshd的配置文件 服务器命令行的远程登录方式 远程复制 先在第一台主机上创建文件 使用scp命令复制 sftp ssh的密钥登录 创建rsa密钥 将密钥文件传给另一台主机…

JavaWeb:文件上传1

欢迎来到“雪碧聊技术”CSDN博客&#xff01; 在这里&#xff0c;您将踏入一个专注于Java开发技术的知识殿堂。无论您是Java编程的初学者&#xff0c;还是具有一定经验的开发者&#xff0c;相信我的博客都能为您提供宝贵的学习资源和实用技巧。作为您的技术向导&#xff0c;我将…