Qt网络编程基础
提供的功能
TCP/IP 客户端和服务器:Qt 网络模块提供了编写 TCP/IP 客户端和服务器的类
低级别类
QTcpSocket
- 用于实现 TCP 客户端功能。通过这个类,可以进行 TCP 连接的创建、数据的发送和接收
QTcpServer
- 用于实现 TCP 服务器功能。通过这个类,可以监听指定的端口,接受客户端的连接请求
QUdpSocket
- 用于实现 UDP 通信。通过这个类,可以进行 UDP 数据报的发送和接收
高级类
用于执行使用通用协议的网络操作
QNetworkRequest
- 表示一个网络请求。通常用来定义请求的 URL、HTTP 头信息等
QNetworkReply
- 表示接收到的网络响应。包含了响应的数据、状态码、头信息等
QNetworkAccessManager
- 用于执行网络操作的管理类。通过这个类,可以发送网络请求并接收响应
承载管理类
QNetworkConfiguration
- 表示一个网络配置(如 Wi-Fi、移动数据等)。包含网络配置相关的信息
QNetworkConfigurationManager
- 管理和查询所有可用的网络配置。可以用来获取当前的网络环境
QNetworkSession
- 表示一个网络会话。通过这个类,可以管理网络连接的建立、维护和关闭
使用配置
要在程序中使用 Qt 网络模块,需要在项目配置文件(.pro 文件)中添加以下语句
QT += network
获取本机的网络信息
概述
-
获取本机网络信息的原因
-
在建立网络通信之前,需要至少获取对方的 IP 地址
-
网络应用中经常需要用到本机的主机名、IP 地址、MAC 地址等网络信息
-
-
传统方法
-
在 Windows 系统中,可以通过调出命令行窗口输入 ipconfig 命令查看相关信息
-
在 Linux 系统中,可以使用 ifconfig 命令查看相关信息
-
-
利用 Qt 实现查询界面和功能
-
利用 Qt,可以做出一个可以查询本机网络信息的界面和相关功能
-
这为后续的网络编程打下一个简单的基础
-
-
Qt 提供的类
-
QHostInfo:用于查询主机信息
-
QNetworkInterface:用于查询网络接口信息
-
关于 QHostInfo 和 QNetworkInterface 的相关函数可以在 Qt 的帮助文档中找到
-
应用实例
-
通过 QHostInfo 和 QNetworkInterface 类获取本地网络所有接口的信息
-
获取本机的网络接口信息,打印在文本浏览框上,点击按钮可直接获取,点击获取本机信息按钮后延时 1s 去刷新获取的信息。点击另一个清空文本信息按钮可以清空文本浏览框上的文本内容
-
项目文件文件第一行添加的代码部分如下
- 1 QT += core gui network
-
mainwindow.h
-
1 #ifndef MAINWINDOW_H
2 #define MAINWINDOW_H
3
4 #include
5 #include
6 #include
7 #include
8 #include
9 #include
10
11 class MainWindow : public QMainWindow
12 {
13 Q_OBJECT
14
15 public:
16 MainWindow(QWidget parent = nullptr);
17 ~MainWindow();
18
19 private:
20 / 点击获取和清空文本按钮 */
21 QPushButton pushButton[2];
22
23 / 文本浏览框用于显示本机的信息 /
24 QTextBrowser textBrowser;
25
26 / 水平 Widget 容器和垂直 Widget 容器/
27 QWidget *hWidget;
28 QWidget vWidget;
29
30 / 水平布局和垂直布局 */
31 QHBoxLayout *hBoxLayout;
32 QVBoxLayout vBoxLayout;
33
34 / 定时器 */
35 QTimer timer;
36
37 / 获取本机的网络的信息,返回类型是 QString /
38 QString getHostInfo();
39
40 private slots:
41 / 定时器槽函数,点击按钮后定时触发 /
42 void timerTimeOut();
43
44 / 显示本机信息 /
45 void showHostInfo();
46
47 / 启动定时器 /
48 void timerStart();
49
50 / 清空 textBrowser 的信息 */
51 void clearHostInfo();
52 };
53 #endif // MAINWINDOW_H
54 -
主要是声明两个按钮和一个文本浏览框。另外还有一个定时器,声明一些槽函数
-
-
mainwindow.cpp
-
1 #include “mainwindow.h”
2 #include
3 #include
4 #include
5 #include
6
7 MainWindow::MainWindow(QWidget parent)
8 : QMainWindow(parent)
9{
10 / 设置位置与大小 /
11 this->setGeometry(0, 0, 800, 480);
12
13 / 点击获取本地信息按钮和清空文本按钮 /
14 pushButton[0] = new QPushButton();
15 pushButton[1] = new QPushButton();
16
17 pushButton[0]->setText(“获取本机信息”);
18 pushButton[1]->setText(“清空文本信息”);
19
20 / 按钮的大小根据文本自适应,
21 * 注意 setSizePolicy 需要在布局中使用 /
22 pushButton[0]->setSizePolicy(QSizePolicy::Fixed,
23 QSizePolicy::Fixed);
24 pushButton[1]->setSizePolicy(QSizePolicy::Fixed,
25 QSizePolicy::Fixed);
26
27 / 水平 Widget 和垂直 Widget 用于添加布局 /
28 hWidget = new QWidget();
29 vWidget = new QWidget();
30
31 / 水平布局和垂直布局 /
32 hBoxLayout = new QHBoxLayout();
33 vBoxLayout = new QVBoxLayout();
34
35 / 文本浏览框 /
36 textBrowser = new QTextBrowser();
37
38 / 添加到水平布局 /
39 hBoxLayout->addWidget(pushButton[0]);
40 hBoxLayout->addWidget(pushButton[1]);
41
42 / 将水平布局设置为 hWidget 的布局 /
43 hWidget->setLayout(hBoxLayout);
44
45 / 将文本浏览框和 hWidget 添加到垂直布局 /
46 vBoxLayout->addWidget(textBrowser);
47 vBoxLayout->addWidget(hWidget);
48
49 / 将垂直布局设置为 vWidget 的布局 /
50 vWidget->setLayout(vBoxLayout);
51
52 / 设置 vWidget 为中心部件 /
53 setCentralWidget(vWidget);
54
55 / 定时器初始化 /
56 timer = new QTimer();
57
58 / 信号槽连接 /
59 connect(pushButton[0], SIGNAL(clicked()),
60 this, SLOT(timerStart()));
61 connect(pushButton[1], SIGNAL(clicked()),
62 this, SLOT(clearHostInfo()));
63 connect(timer, SIGNAL(timeout()),
64 this, SLOT(timerTimeOut()));
65 }
66
67 MainWindow::~MainWindow()
68 {
69 }
70
71
72 void MainWindow::timerStart()
73 {
74 / 清空文本 /
75 textBrowser->clear();
76
77 / 定时 1s /
78 timer->start(1000);
79 }
80
81 void MainWindow::timerTimeOut()
82 {
83 / 显示本机信息 /
84 showHostInfo();
85
86 / 停止定时器 /
87 timer->stop();
88 }
89
90 QString MainWindow::getHostInfo()
91 {
92 / 通过 QHostInfo 的 localHostName 函数获取主机名称 /
93 QString str = “主机名称:” + QHostInfo::localHostName() + “\n”;
94
95 / 获取所有的网络接口,
96 * QNetworkInterface 类提供主机的 IP 地址和网络接口的列表 /
97 QList list
98 = QNetworkInterface::allInterfaces();
99
100 / 遍历 list /
101 foreach (QNetworkInterface interface, list) {
102 str+= “网卡设备:” + interface.name() + “\n”;
103 str+= “MAC 地址:” + interface.hardwareAddress() + “\n”;
104
105 / QNetworkAddressEntry 类存储 IP 地址子网掩码和广播地址 /
106 QList entryList
107 = interface.addressEntries();
108
109 / 遍历 entryList /
110 foreach (QNetworkAddressEntry entry, entryList) {
111 / 过滤 IPv6 地址,只留下 IPv4 /
112 if (entry.ip().protocol() ==
113 QAbstractSocket::IPv4Protocol) {
114 str+= “IP 地址:” + entry.ip().toString() + “\n”;
115 str+= “子网掩码:” + entry.netmask().toString() + “\n”;
116 str+= “广播地址:” + entry.broadcast().toString() + “\n\n”;
117 }
118 }
119 }
120
121 / 返回网络信息 /
122 return str;
123 }
124
125 void MainWindow::showHostInfo()
126 {
127 / 获取本机信息后显示到 textBrowser /
128 textBrowser->insertPlainText(getHostInfo());
129 }
130
131 void MainWindow::clearHostInfo()
132 {
133 / 判断 textBrowser 是否为空,如果不为空则清空文本 /
134 if (!textBrowser->toPlainText().isEmpty())
135
136 / 清空文本 */
137 textBrowser->clear();
138 } -
第 90~123 行,是本例最重要的代码
-
获取主机名
- 第 93 行,通过 QHostInfo 的 localHostName 函数获取主机名称
-
获取网络接口列表、提取网络信息
-
第 97~98 行,通过 QNetworkInterface::allInterfaces() 获取网络接口列表。该列表是一个 list 类,存储了 IP 地址、子网掩码和广播地址的信息
-
如果用 qDebug() 函数打印出 list,可以发现获取了所有的网络信息
-
为了提取网络接口中的网络信息,使用 QNetworkAddressEntry
-
-
获取网络条目
-
第 106~107 行,使用 QNetworkAddressEntry 从 interface 接口里调用 addressEntries() 函数,获取所有的条目
-
然后,可以使用 QNetworkAddressEntry 对象 entry 获取 IP 地址、子网掩码和广播地址
-
-
筛选 IPv4 信息
-
第 110~118 行,因为获取的 entries 在一个 QNetworkInterface 下可能包含两个 IP,分别是 IPv4 和 IPv6
-
使用 ip().protocol() 来判断协议的类型,只留下 IPv4 类型的信息。这种筛选信息的方式在编写程序时常常需要
-
-
-
程序运行效果
-
打印网络信息
- 用户点击“获取本机信息”按钮后,文本浏览框内会打印出本机的网络信息。这些信息包括主机名、网卡名、IP 地址等
-
过滤 IPv6 信息
-
由于过滤掉了 IPv6 信息,打印的网络信息中仅包含 IPv4 地址
-
通常一个网卡会有两个 IP 地址,一个是 IPv4 地址,另一个是 IPv6 地址
-
-
网卡设备描述
-
网卡设备 lo 是本地回环网卡,用于本地主机的内部通信
-
另一个网卡设备 ens33 是虚拟机的网卡,由 VMware 虚拟化平台创建
-
-
清空文本信息
- 用户点击“清空文本信息”按钮后,会清空文本浏览框中的所有网络信息