网络与序列化
# 05.网络与序列化
- 5.1 底层网络
- 5.1.1 TCP/UDP套接字
- 5.1.2 QLocalSocket
- 5.1.3 QNetworkProxy
- 5.2 协议支持
- 5.2.1 QUrl
- 5.2.2 QUrlQuery
- 5.2.3 QHostInfo
- 5.2.4 QNetworkInterface
- 5.3 序列化
- 5.3.1 二进制序列化
- 5.3.2 JSON序列化
- 5.3.3 XML序列化
- 5.3.4 自定义序列化
- 5.3.5 序列化总结
# 5.1 底层网络
底层网络
- QTcpSocket/QUdpSocket:TCP/UDP套接字
- QLocalSocket:本地套接字(进程间通信)
- QNetworkProxy:网络代理支持
# 5.2 协议支持
协议支持
- QUrl/QUrlQuery:URL 解析与构建
- QHostInfo:主机信息查询
- QNetworkInterface:网络接口信息
# 5.2.1 QUrl
QUrl 基本用法
#include <QUrl>
#include <QDebug>
int main() {
// 创建 URL
QUrl url("https://www.example.com/path/to/resource?key1=value1&key2=value2");
// 获取 URL 各部分
qDebug() << "Scheme:" << url.scheme(); // https
qDebug() << "Host:" << url.host(); // www.example.com
qDebug() << "Path:" << url.path(); // /path/to/resource
qDebug() << "Query:" << url.query(); // key1=value1&key2=value2
// 构建 URL
QUrl newUrl;
newUrl.setScheme("http");
newUrl.setHost("example.org");
newUrl.setPath("/new/path");
newUrl.setQuery("param1=value1¶m2=value2");
qDebug() << "New URL:" << newUrl.toString(); // http://example.org/new/path?param1=value1¶m2=value2
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 5.2.2 QUrlQuery
QUrlQuery 基本用法
#include <QUrlQuery>
#include <QDebug>
int main() {
// 创建 QUrlQuery
QUrlQuery query;
query.addQueryItem("key1", "value1");
query.addQueryItem("key2", "value2");
// 获取查询参数
qDebug() << "Query string:" << query.toString(); // key1=value1&key2=value2
qDebug() << "Value of key1:" << query.queryItemValue("key1"); // value1
// 修改查询参数
query.removeQueryItem("key1");
query.addQueryItem("key3", "value3");
qDebug() << "Updated query:" << query.toString(); // key2=value2&key3=value3
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 5.2.3 QHostInfo
QHostInfo 用于查询主机名、IP 地址等信息。
(1)基本用法
#include <QHostInfo>
#include <QDebug>
int main() {
// 查询主机名
QString hostName = QHostInfo::localHostName();
qDebug() << "Local host name:" << hostName;
// 查询主机信息
QHostInfo hostInfo = QHostInfo::fromName("www.example.com");
if (hostInfo.error() == QHostInfo::NoError) {
QList<QHostAddress> addresses = hostInfo.addresses();
for (const QHostAddress &address : addresses) {
qDebug() << "IP address:" << address.toString();
}
} else {
qDebug() << "Error:" << hostInfo.errorString();
}
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
(2)常用方法
localHostName():获取本地主机名。fromName(const QString &name):根据主机名查询主机信息。addresses():获取主机的 IP 地址列表。error():获取查询错误信息。
# 5.2.4 QNetworkInterface
QNetworkInterface 用于获取网络接口的详细信息,如 IP 地址、MAC 地址等。
(1)基本用法
#include <QNetworkInterface>
#include <QDebug>
int main() {
// 获取所有网络接口
QList<QNetworkInterface> interfaces = QNetworkInterface::allInterfaces();
for (const QNetworkInterface &interface : interfaces) {
qDebug() << "Interface:" << interface.name();
qDebug() << " Hardware address:" << interface.hardwareAddress();
// 获取 IP 地址
QList<QNetworkAddressEntry> entries = interface.addressEntries();
for (const QNetworkAddressEntry &entry : entries) {
qDebug() << " IP:" << entry.ip().toString();
qDebug() << " Netmask:" << entry.netmask().toString();
qDebug() << " Broadcast:" << entry.broadcast().toString();
}
}
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
(2)常用方法
allInterfaces():获取所有网络接口。name():获取网络接口名称。hardwareAddress():获取网络接口的 MAC 地址。addressEntries():获取网络接口的 IP 地址信息。
# 5.3 序列化与数据格式
数据格式支持
- QJsonDocument/QJsonObject/QJsonArray:JSON 支持
- QCbor:CBOR 格式支持(Qt 6)
- QDataStream:二进制序列化
# 5.3.1 二进制序列化
QDataStream 是 Qt 中用于二进制数据序列化和反序列化的核心类。
1.序列化
#include <QFile>
#include <QDataStream>
QFile file("data.bin");
if (!file.open(QIODevice::WriteOnly)) {
qDebug() << "Failed to open file!";
return;
}
QDataStream out(&file);
out << QString("Hello, Qt!") << qint32(123) << QDate::currentDate();
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
反序列化
#include <QFile>
#include <QDataStream>
QFile file("data.bin");
if (!file.open(QIODevice::ReadOnly)) {
qDebug() << "Failed to open file!";
return;
}
QDataStream in(&file);
QString text;
qint32 number;
QDate date;
in >> text >> number >> date;
qDebug() << text << number << date;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 5.3.2 JSON序列化
QJsonDocument 用于处理 JSON 数据。
1.序列化
#include <QJsonDocument>
#include <QJsonObject>
#include <QFile>
QJsonObject json;
json["name"] = "Qt";
json["version"] = 6.2;
json["released"] = true;
QJsonDocument doc(json);
QByteArray jsonData = doc.toJson();
QFile file("data.json");
if (!file.open(QIODevice::WriteOnly)) {
qDebug() << "Failed to open file!";
return;
}
file.write(jsonData);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2.反序列化
#include <QJsonDocument>
#include <QJsonObject>
#include <QFile>
QFile file("data.json");
if (!file.open(QIODevice::ReadOnly)) {
qDebug() << "Failed to open file!";
return;
}
QByteArray jsonData = file.readAll();
QJsonDocument doc = QJsonDocument::fromJson(jsonData);
QJsonObject json = doc.object();
qDebug() << "Name:" << json["name"].toString();
qDebug() << "Version:" << json["version"].toDouble();
qDebug() << "Released:" << json["released"].toBool();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 5.3.3 XML序列化
1.序列化:QXmlStreamWriter 用于生成 XML 数据。
#include <QFile>
#include <QXmlStreamWriter>
QFile file("data.xml");
if (!file.open(QIODevice::WriteOnly)) {
qDebug() << "Failed to open file!";
return;
}
QXmlStreamWriter xml(&file);
xml.setAutoFormatting(true);
xml.writeStartDocument();
xml.writeStartElement("root");
xml.writeTextElement("name", "Qt");
xml.writeTextElement("version", "6.2");
xml.writeEndElement();
xml.writeEndDocument();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2.反序列化:QXmlStreamReader 用于解析 XML 数据。
#include <QFile>
#include <QXmlStreamReader>
QFile file("data.xml");
if (!file.open(QIODevice::ReadOnly)) {
qDebug() << "Failed to open file!";
return;
}
QXmlStreamReader xml(&file);
while (!xml.atEnd()) {
xml.readNext();
if (xml.isStartElement()) {
if (xml.name() == "name") {
qDebug() << "Name:" << xml.readElementText();
} else if (xml.name() == "version") {
qDebug() << "Version:" << xml.readElementText();
}
}
}
if (xml.hasError()) {
qDebug() << "XML error:" << xml.errorString();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 5.3.4 自定义序列化
可以通过重载 operator<< 和 operator>> 实现自定义类型的序列化。
1.自定义类型
struct Person {
QString name;
int age;
};
1
2
3
4
2
3
4
2.序列化
QDataStream &operator<<(QDataStream &out, const Person &person) {
out << person.name << person.age;
return out;
}
1
2
3
4
2
3
4
3.反序列化
QDataStream &operator>>(QDataStream &in, Person &person) {
in >> person.name >> person.age;
return in;
}
1
2
3
4
2
3
4
4.使用
Person person = {"Alice", 25};
QFile file("person.dat");
if (!file.open(QIODevice::WriteOnly)) {
qDebug() << "Failed to open file!";
return;
}
QDataStream out(&file);
out << person;
file.close();
if (!file.open(QIODevice::ReadOnly)) {
qDebug() << "Failed to open file!";
return;
}
Person loadedPerson;
QDataStream in(&file);
in >> loadedPerson;
qDebug() << "Name:" << loadedPerson.name << "Age:" << loadedPerson.age;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 5.3.5 序列化总结
QDataStream:用于二进制数据的序列化和反序列化。QJsonDocument:用于 JSON 数据的序列化和反序列化。QXmlStreamWriter和QXmlStreamReader:用于 XML 数据的生成和解析。- 自定义序列化:通过重载
operator<<和operator>>实现自定义类型的序列化。
上次更新: 2026/06/10, 11:13:41