SSL 服务器与客户端
使用 QSslSockets 设置安全的远程对象网络。
当需要通过无法完全控制的网络传输数据时,对通信进行加密至关重要。本示例中的两个应用程序演示了如何通过 SSL 连接共享远程对象,以及如何访问这些对象。

sslserver和sslcppclient都使用自定义的根 CA 证书来验证彼此的证书,这些证书均位于 sslserver/cert 目录下。
SSL 服务器
sslserver已配置证书和私钥。
autoconfig=QSslConfiguration::defaultConfiguration();
config.setCaCertificates(QSslCertificate::fromPath(QStringLiteral(":/sslcert/rootCA.pem")));
QFile certificateFile(QStringLiteral(":/sslcert/server.crt"));
if(certificateFile.open(QIODevice::ReadOnly|QIODevice::Text))
config.setLocalCertificate(QSslCertificate(certificateFile.readAll(),QSsl::Pem));
else
qFatal("Could not open certificate file");
QFile keyFile(QStringLiteral(":/sslcert/server.key"));
if(keyFile.open(QIODevice::ReadOnly|QIODevice::Text)) {
QSslKey key(keyFile.readAll(),QSsl::Rsa,QSsl::Pem,QSsl::PrivateKey);
if(key.isNull())
qFatal("Key is not valid");
config.setPrivateKey(key);
}else{
qFatal("Could not open key file");
}
config.setPeerVerifyMode(QSslSocket::VerifyPeer);
QSslConfiguration::setDefaultConfiguration(config);随后,它创建了一个QRemoteObjectHost 对象和一个QSslServer 对象。QSslServer 对象监听65511端口。接着,对QRemoteObjectHost 对象调用setHostUrl方法,并传入QSslServer 对象的URL。
QRemoteObjectHost host;
QSslServer server;
server.listen(QHostAddress::Any, 65511);
host.setHostUrl(server.serverAddress().toString(), QRemoteObjectHost::AllowExternalRegistration);使用一个 lambda 表达式来处理 errorOccurred 信号,将错误输出到终端。第二个 lambda 表达式连接到 pendingConnectionAvailable 信号,该信号连接了一个错误处理程序,并使用传入的套接字作为参数,在QRemoteObjectHost 对象上调用 addHostSideConnection 方法,使主机对象使用该套接字进行通信。
QObject::connect(&server, &QSslServer::errorOccurred,
[](QSslSocket*socket,QAbstractSocket::SocketErrorerror) {
Q_UNUSED(socket);
qDebug() << "QSslServer::errorOccurred" << error;
});
QObject::connect(&server, &QSslServer::pendingConnectionAvailable, [&server, &host]() {
qDebug() << "New connection available";
QSslSocket*socket =qobject_cast<QSslSocket*>(server.nextPendingConnection());
Q_ASSERT(socket);
QObject::connect(socket, &QSslSocket::errorOccurred,
[](QAbstractSocket::SocketErrorerror) {
qDebug() << "QSslSocket::error" << error;
});
host.addHostSideConnection(socket);
});最后,创建一个 MinuteTimer 对象,并以该 MinuteTimer 对象作为参数调用QRemoteObjectHost 对象的 enableRemoting 方法,以便将其共享。
MinuteTimer timer;
host.enableRemoting(&timer);SSL 客户端
sslcppclient设置了根 CA 证书,然后创建了一个 Tester 对象。
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
auto config = QSslConfiguration::defaultConfiguration();
config.setCaCertificates(QSslCertificate::fromPath(QStringLiteral(":/sslcert/rootCA.pem")));
QSslConfiguration::setDefaultConfiguration(config);
Tester t;
return a.exec();
}在 Tester 构造函数中,会创建一个临时QRemoteObjectNode 对象,并使用 setupConnection 方法创建和配置一个QSslSocket 对象。连接一个错误处理程序后,QRemoteObjectNode 对象通过调用其 addClientSideConnection 方法来使用该QSslSocket 对象。
QRemoteObjectNode m_client;
autosocket=setupConnection();
connect(socket, &QSslSocket::errorOccurred,
socket, [](QAbstractSocket::SocketErrorerror){
qDebug() << "QSslSocket::error" << error;
}) ;
m_client.addClientSideConnection(socket);随后,通过在QRemoteObjectNode 对象上调用acquire方法,将Tester类的三个QScopedPointer 成员连接到MinuteTimer的三个副本。最后,使用QTimer::singleShot 方法四次,在延迟后调用reset。
ptr1.reset(m_client.acquire< MinuteTimerReplica >());
ptr2.reset(m_client.acquire< MinuteTimerReplica >());
ptr3.reset(m_client.acquire< MinuteTimerReplica >());
QTimer::singleShot(0, this, &Tester::clear);
QTimer::singleShot(1, this, &Tester::clear);
QTimer::singleShot(10000, this, &Tester::clear);
QTimer::singleShot(11000, this, &Tester::clear);前三次调用 Tester::clear 时,每次都会检查一个指针是否已绑定,并将其重置,且每次检查的指针都不相同。第四次调用时,会导致应用程序退出。
voidclear()
{
static inti= 0;
if(i== 0) {
i++;
if(ptr1.isNull())
qCritical() << "Pointer 1 was not set";
ptr1.reset();
}else if(i== 1) {
i++;
if(ptr2.isNull())
qCritical() << "Pointer 2 was not set";
ptr2.reset();
}else if(i== 2) {
i++;
if(ptr3.isNull())
qCritical() << "Pointer 3 was not set";
ptr3.reset();
}else{
qApp->quit();
}
}© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.