【嵌入式Qt开发入门】Qt如何网络编程——获取本机的网络信息

news2024/11/23 23:50:26

        Qt 网络模块为我们提供了编写TCP/IP客户端和服务器的类。它提供了较低级别的类,例如代表低级网络概念的 QTcpSocket,QTcpServer 和 QUdpSocket,以及诸如 QNetworkRequest, QNetworkReply 和 QNetworkAccessManager 之类的高级类来执行使用通用协议的网络操作。它 还提供了诸如QNetworkConfiguration,QNetworkConfigurationManager和QNetworkSession等类, 实现承载管理。

        想要在程序中使用 Qt 网络模块,我们需要在 pro 项目配置文件里增加下面的一条语句。

QT     += network

获取本机的网络信息

        为什么先获取本机网络信息呢?在建立网络通信之前我们至少得获取对方的 IP 地址。在网络应用中,经常需要用到本机的主机名、IP 地址、MAC 地址等网络信息,通常通在 Windows 通过调出命令行 cmd 窗口输入ipconfig或者在 Linux 系统中使用ifconfig命令就可以查看相关信息了,在这里我们利用Qt做出一个可以查询的界面和功能出来,为了后面的网络编程打下一个简单的基础。

        Qt 提供了 QHostInfo 和 QNetworkInterface 类可以用于此类信息查询。更多关于 QHostInfo 和 QNetworkInterface 的相关函数可以在 Qt 的帮助文档中找到。下面我们写代码时会使用到相关的函数,有清楚的注释。

应用实例

        项目目的:了解如何通过QHostInfo和QNetworkInterface类获取本地网络所有接口的信息。

        项目名称:networkhostinfo ,获取本机网络接口信息。        

        获取本机的网络接口信息,打印在文本浏览框上,点击按钮可直接获取,为了清楚看见是重新获取的过程,本例点击获取本机信息按钮后延时 1s 去刷新获取的信息。点击另一个清空文本信息按钮可以清空文本浏览框上的文本内容。

        项目文件 networkhostinfo.pro 文件第一行添加的代码部分如下。

QT       += core gui network

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++11

# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    main.cpp \
    mainwindow.cpp

HEADERS += \
    mainwindow.h

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

        在头文件“mainwindow.h”具体代码如下。

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QPushButton>
#include <QTextBrowser>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QTimer>

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    /* 点击获取和清空文本按钮 */
    QPushButton *pushButton[2];

    /* 文本浏览框用于显示本机的信息 */
    QTextBrowser *textBrowser;

    /* 水平Widget容器和垂直Widget容器*/
    QWidget *hWidget;
    QWidget *vWidget;

    /* 水平布局和垂直布局 */
    QHBoxLayout *hBoxLayout;
    QVBoxLayout *vBoxLayout;

    /* 定时器 */
    QTimer *timer;

    /* 获取本机的网络的信息,返回类型是QString */
    QString getHostInfo();

private slots:
    /* 定时器槽函数,点击按钮后定时触发 */
    void timerTimeOut();

    /* 显示本机信息 */
    void showHostInfo();

    /* 启动定时器 */
    void timerStart();

    /* 清空textBrowser的信息 */
    void clearHostInfo();
};
#endif // MAINWINDOW_H

        头文件里主要是声明两个按钮和一个文本浏览框。另外还有一个定时器,声明一些槽函数, 比较简单。 在源文件“mainwindow.cpp”具体代码如下。

#include "mainwindow.h"
#include <QNetworkInterface>
#include <QHostInfo>
#include <QThread>
#include <QDebug>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    /* 设置位置与大小 */
    this->setGeometry(0, 0, 800, 480);

    /* 点击获取本地信息按钮和清空文本按钮 */
    pushButton[0] = new QPushButton();
    pushButton[1] = new QPushButton();

    pushButton[0]->setText("获取本机信息");
    pushButton[1]->setText("清空文本信息");

    /* 按钮的大小根据文本自适应,
     * 注意setSizePolicy需要在布局中使用 */
    pushButton[0]->setSizePolicy(QSizePolicy::Fixed,
                                 QSizePolicy::Fixed);
    pushButton[1]->setSizePolicy(QSizePolicy::Fixed,
                                 QSizePolicy::Fixed);

    /* 水平Widget和垂直Widget用于添加布局 */
    hWidget = new QWidget();
    vWidget = new QWidget();

    /* 水平布局和垂直布局 */
    hBoxLayout = new QHBoxLayout();
    vBoxLayout = new QVBoxLayout();

    /* 文本浏览框 */
    textBrowser = new QTextBrowser();

    /* 添加到水平布局 */
    hBoxLayout->addWidget(pushButton[0]);
    hBoxLayout->addWidget(pushButton[1]);

    /* 将水平布局设置为hWidget的布局 */
    hWidget->setLayout(hBoxLayout);

    /* 将文本浏览框和hWidget添加到垂直布局 */
    vBoxLayout->addWidget(textBrowser);
    vBoxLayout->addWidget(hWidget);

    /* 将垂直布局设置为vWidget的布局 */
    vWidget->setLayout(vBoxLayout);

    /* 设置vWidget为中心部件 */
    setCentralWidget(vWidget);

    /* 定时器初始化 */
    timer = new QTimer();

    /* 信号槽连接 */
    connect(pushButton[0], SIGNAL(clicked()),
            this, SLOT(timerStart()));
    connect(pushButton[1], SIGNAL(clicked()),
            this, SLOT(clearHostInfo()));
    connect(timer, SIGNAL(timeout()),
            this, SLOT(timerTimeOut()));
}

MainWindow::~MainWindow()
{
}

void MainWindow::timerStart()
{
    /* 清空文本 */
    textBrowser->clear();

    /* 定时1s */
    timer->start(1000);
}

void MainWindow::timerTimeOut()
{
    /* 显示本机信息 */
    showHostInfo();

    /* 停止定时器 */
    timer->stop();
}

QString MainWindow::getHostInfo()
{
    /* 通过QHostInfo的localHostName函数获取主机名称 */
    QString str = "主机名称:" + QHostInfo::localHostName() + "\n";

    /* 获取所有的网络接口,
     * QNetworkInterface类提供主机的IP地址和网络接口的列表 */
    QList<QNetworkInterface> list
            = QNetworkInterface::allInterfaces();

    /* 遍历list */
    foreach (QNetworkInterface interface, list) {
        str+= "网卡设备:" + interface.name() + "\n";
        str+= "MAC地址:" + interface.hardwareAddress() + "\n";

        /* QNetworkAddressEntry类存储IP地址子网掩码和广播地址 */
        QList<QNetworkAddressEntry> entryList
                = interface.addressEntries();

        /* 遍历entryList */
        foreach (QNetworkAddressEntry entry, entryList) {
            /* 过滤IPv6地址,只留下IPv4 */
            if (entry.ip().protocol() ==
                    QAbstractSocket::IPv4Protocol) {
                str+= "IP 地址:" + entry.ip().toString() + "\n";
                str+= "子网掩码:" + entry.netmask().toString() + "\n";
                str+= "广播地址:" + entry.broadcast().toString() + "\n\n";
            }
        }
    }

    /* 返回网络信息 */
    return str;
}

void MainWindow::showHostInfo()
{
    /* 获取本机信息后显示到textBrowser */
    textBrowser->insertPlainText(getHostInfo());
}

void MainWindow::clearHostInfo()
{
    /* 判断textBrowser是否为空,如果不为空则清空文本 */
    if (!textBrowser->toPlainText().isEmpty())

        /* 清空文本 */
        textBrowser->clear();
}

        首先,通过 QHostInfo 的 localHostName 函数获取主机名称。

         然后通过 QNetworkInterface::allInterfaces()获取网络接口列表 list 类存储 IP 地址子网掩码和广播地址。如果我们用 qDebug()函数打印出 list,可以发现获取了所有的网络信息。 而我们要提取网络里面的网络信息使用 QNetworkAddressEntry。

        再用QNetworkAddressEntry 从 interface 接口里使用函数 addressEntries(), 获取所有的条目。就可以使用 QNetworkAddressEntry 的对象 entry 获取 IP 地址子网掩码和广播地址。

        因为获取的entries在一个 QNetworkInterface下可能有两个IP,分别是ipv4 和 ipv6。这里使用ip().protocol()来判断协议的类型,只留下 ipv4 类型的信息。筛选信息在我们写程序常常需要的。

程序运行效果

        点击获取本机信息,在文本浏览框内就打印出本机的网络信息(包括了主机名,网卡名, ip 地址等)。这里因为过滤掉了 IPv6 的信息。通常一个网卡有两个 ip 地址,一个是 ipv4,另一 个是 ipv6 的地址。下面的网卡设备 lo,是本地回环网卡。另一个 ens33 是虚拟机的网卡,由 VMware 虚拟出来的。点击清空文本信息会清空文本浏览框里的网络信息。

 

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

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

相关文章

2023世界人工智能大会,和鲸科技入选中国信通院《2023大模型和AIGC产业图谱》

近日&#xff0c;2023 世界人工智能大会&#xff08;WAIC&#xff09;“聚焦大模型时代 AIGC 新浪潮”论坛上&#xff0c;中国信息通信研究院&#xff08;以下简称“中国信通院”&#xff09;正式发布《2023 大模型和AIGC产业图谱》&#xff08;以下称“图谱”&#xff09;。和…

一、简易搭建本地CAS服务端

CAS服务端war包下载 https://repo1.maven.org/maven2/org/apereo/cas/cas-server-webapp-tomcat/5.3.14/ 可使用迅雷下载cas-server-webapp-tomcat-5.3.14.war &#xff0c;速度很快 将wab包放到本地tomcat的webapps下D:\tomcat\apache-tomcat-8.5.63\webapps\cas\WEB-INF\clas…

springboot项目实战-API接口限流

1.简介 对接口限流的目的是通过对并发访问/请求进行限速&#xff0c;或者对一个时间窗口内的请求进行限速来保护系统&#xff0c;一旦达到限制速率则可以拒绝服务、排队或等待、降级等处理。 1.1.为什么需要限流? 大量正常用户高频访问导致服务器宕机恶意用户高频访问导致服…

国产SAAS平台中类似Jira的有哪些值得关注的选择?

在项目管理市场中&#xff0c;Jira是一款非常知名的软件工具。它可以帮助团队成员更好地管理和协作&#xff0c;提高项目效率和质量。然而&#xff0c;Jira并不是完美的&#xff0c;存在诸如复杂操作、高昂费用等不足之处。因此&#xff0c;许多国内企业开始尝试寻找替代品&…

Yolov7配置CoCo精度显示问题实操

1、安装pycocotools工具&#xff0c; 使用yolov7项目中test.py&#xff0c;安装pycocotools时&#xff0c;命令无法直接安装成功。 本次操作在Linux上进行&#xff1a; GitHub - cocodataset/cocoapi: COCO API - Dataset http://cocodataset.org/COCO API - Dataset http:…

uniapp 打包安卓apk (原生App)云打包

uniapp 打包安卓apk (原生App)云打包 hbuilder中操作 项目的一些配置appid DCloud appid 用途/作用/使用说明&#xff1a; https://ask.dcloud.net.cn/article/35907 右键我们项目目录-》发行-》原生APP-云打包 说明&#xff1a; 1. 打包安卓&#xff0c;只选择安卓打包项&…

【Pytest】Allure测试报告的安装与环境配置

文章目录 一、安装配置JAVA环境1、下载jdk2、配置环境变量3、检验 二、安装allure-pytest插件三、下载安装Allure1、下载allure2、配置环境变量3、检验 一、安装配置JAVA环境 Allure基于Java开发&#xff0c;因此需要提前安装Java 8 或以上版本的环境。 1、下载jdk jdk下载地…

2023愚人杯-easy_base

0x00 前言 CTF 加解密合集&#xff1a;CTF 加解密合集 0x01 题目 4C455A5645334C44474A55484D5A42544F5132574956525A50464E464F4E4C474D4656454D334359474A554751564B4949493255535532464E42544643504A350x02 Write Up 直接通过现成的工具即可&#xff1a; 以上

C++教程——STL

STL基本概念 容器算法迭代器 Vector容器 vector存放内置数据类型 vector存放自定义数据类型 vector容器嵌套容器 string容器 string的构造函数 string赋值操作 string字符串拼接 string查找与替换 string字符串比较 string字符存取 string插入与删除 string字串获取

React+Antd+Typescript:封装条件查询组件

文章目录 概要整体架构思路概要 这是筛选组件的效果图。一般使用场景,根据需求快速筛选出符合条件的数据。 那么这个筛选组件,就是默认一些常见的条件,比如明天或者昨天,虽然这个条件,我们可以通过antd的日期控件来实现,但缺点就是操作起来有点麻烦。通过预设一些条件,…

学习记录——BiSeNetV1、BiSeNetV2、BiSeNetV3、PIDNet

BiSeNetV1 BiSeNetV1为了在不影响速度的情况下&#xff0c;同时收集到空间信息和语义信息&#xff0c;设计了两条路&#xff1a; Spatial Path: 用了三层stride为 2 的卷积&#xff0c;卷积BNRELU模块。最后提取了相当于原图像 1/8 的输出特征图。由于它利用了较大尺度的特征图…

C++_简单模拟实现string的增删查改

目录 一、模拟reserve 二、模拟push_back 三、模拟append 四、模拟operator 五、模拟insert 六、模拟erase 七、模拟find 八、模拟substr 一、模拟reserve 要添加数据&#xff0c;首先要考虑的是扩容。有必要用reserve辅助扩容。reserve的作用就是给一个预期的值作为扩…

【雕爷学编程】Arduino动手做(138)---64位WS2812点阵屏模块4

37款传感器与执行器的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&am…

Vue源码分析拓展 - 响应式系统搭建

Vue里面如何追踪变化 当你把一个普通的JavaScript对象传入Vue实例作为data选项&#xff0c;Vue将遍历此对象所有的属性&#xff0c;并使用Object.defineProperty把这些属性全部转为getter/setter. 这些getter/setter.对用户来说是不可见的&#xff0c;但是在内部他们让Vue能够…

Nginx配置汇总

一、Nginx概念 Nginx是目前负载均衡技术中的主流方案&#xff0c;几乎绝大部分项目都会使用它&#xff0c;Nginx是一个轻量级的高性能HTTP反向代理服务器&#xff0c;同时它也是一个通用类型的代理服务器&#xff0c;支持绝大部分协议&#xff0c;如TCP、UDP、SMTP、HTTPS等。…

Java028——Runtime 类

一、Runtime 类介绍 Runtime 类是JDK 提供的运行时类&#xff0c;该类为 Java 程序提供了与当前运行环境相连接的一个通道,Java 程序可以利用该类对当前的运行环境执行一些简单的操作。 二、Runtime 对象的创建 Runtime 类对象不能使用 new 关键字创建&#xff0c;只能通过 …

【LeetCode: 167. 两数之和 II - 输入有序数组 | 双指针专题 】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

C++之final关键字用法(一百六十)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

Loki+promtail+Grafana监控docker容器日志

目标&#xff1a;监控docker容器的日志&#xff0c;适用于生成环境 效果&#xff1a; 需要的工具&#xff1a;Loki&#xff0c;promtail&#xff0c;Grafana 通过安装promtail容器收集日志&#xff0c;并把日志发送给loki存储处理&#xff0c;由Grafana展示日志。 参考官网的…

[SSM]MyBatis的注解式开发与PageHelper

目录 十五、MyBatis使用PageHelper 15.1 limit分页 15.2PageHelper插件 第一步&#xff1a;引入依赖pom.xml 第二步&#xff1a;在mybatis-config.xml文件中配置插件 第三步&#xff1a;编写Java代码 十六、MyBatis的注解式开发 16.1Insert 16.2Delete 16.3Update 1…