1. Qt6使用https协议在客户端发送一条文字消息到服务器端。 之前的 HTTP 示例改成 HTTPS ,这样客户端通过 TLS 加密发送一条文字消息到服务器端。 这里有几个关键点需要注意:
🔑 关键变化
Qt 客户端
使用 QNetworkAccessManager + QNetworkRequest,但 URL 必须是 https://
需要配置 QSslConfiguration(证书验证、加密套件等)
如果是自签名证书,需要在客户端信任它(开发阶段可以临时忽略验证)
服务器端
Qt 自带的 QTcpServer 不直接支持 HTTPS,需要用 QSslSocket 或 QTcpServer+QSslSocket 组合
必须加载服务器的私钥和证书(PEM 格式)
证书可以用 openssl 自签名生成
1️⃣ 生成自签名证书(开发测试用)
在终端执行:
1 openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ -keyout server.key -out server.crt
然后合并成一个 .pem 文件:
1 cat server.key server.crt > server.pem
2️⃣ HTTPS 服务器(Qt6)
httpsserver.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 #ifndef HTTPSSERVER_H #define HTTPSSERVER_H #include <QObject> #include <QTcpServer> #include <QSslSocket> #include <QSslCertificate> #include <QSslKey> class HttpsServer : public QObject{ Q_OBJECT public : explicit HttpsServer (QObject *parent = nullptr ) ; private slots: void onNewConnection () ; void onEncrypted () ; void onReadyRead () ; private : QTcpServer server; QSslCertificate certificate; QSslKey privateKey; }; #endif
httpsserver.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 #include "httpsserver.h" #include <QFile> #include <QDebug> HttpsServer::HttpsServer (QObject *parent) : QObject (parent) { QFile certFile ("server.pem" ) ; if (!certFile.open (QIODevice::ReadOnly)) { qWarning () << "Cannot open certificate file" ; return ; } certificate = QSslCertificate (&certFile, QSsl::Pem); certFile.seek (0 ); privateKey = QSslKey (&certFile, QSsl::Rsa, QSsl::Pem); if (!server.listen (QHostAddress::Any, 8443 )) { qWarning () << "Failed to start HTTPS server" ; return ; } qDebug () << "HTTPS Server listening on port 8443" ; connect (&server, &QTcpServer::newConnection, this , &HttpsServer::onNewConnection); } void HttpsServer::onNewConnection () { QTcpSocket *tcpSocket = server.nextPendingConnection (); QSslSocket *sslSocket = new QSslSocket (this ); sslSocket->setSocketDescriptor (tcpSocket->socketDescriptor ()); sslSocket->setLocalCertificate (certificate); sslSocket->setPrivateKey (privateKey); sslSocket->setProtocol (QSsl::TlsV1_2OrLater); connect (sslSocket, &QSslSocket::encrypted, this , &HttpsServer::onEncrypted); connect (sslSocket, &QSslSocket::readyRead, this , &HttpsServer::onReadyRead); sslSocket->startServerEncryption (); tcpSocket->deleteLater (); } void HttpsServer::onEncrypted () { qDebug () << "SSL handshake completed" ; } void HttpsServer::onReadyRead () { QSslSocket *socket = qobject_cast <QSslSocket*>(sender ()); if (!socket) return ; QByteArray request = socket->readAll (); qDebug ().noquote () << request; int idx = request.indexOf ("\r\n\r\n" ); QByteArray body; if (idx != -1 ) { body = request.mid (idx + 4 ).trimmed (); } qDebug () << "Received:" << QString::fromUtf8 (body); QByteArray responseBody = "Server received: " + body; QByteArray response = "HTTP/1.1 200 OK\r\n" "Content-Type: text/plain\r\n" "Content-Length: " + QByteArray::number (responseBody.size ()) + "\r\n" "\r\n" + responseBody; socket->write (response); socket->disconnectFromHost (); }
3️⃣ HTTPS 客户端(Qt6)
httpsclient.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 #ifndef HTTPSCLIENT_H #define HTTPSCLIENT_H #include <QObject> #include <QNetworkAccessManager> #include <QNetworkReply> class HttpsClient : public QObject{ Q_OBJECT public : explicit HttpsClient (QObject *parent = nullptr ) ; void sendMessage (const QUrl &url, const QString &message) ; private slots: void onFinished (QNetworkReply *reply) ; void onSslErrors (QNetworkReply *reply, const QList<QSslError> &errors) ; private : QNetworkAccessManager manager; }; #endif
httpsclient.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 #include "httpsclient.h" #include <QDebug> #include <QNetworkRequest> #include <QSslConfiguration> HttpsClient::HttpsClient (QObject *parent) : QObject (parent) { connect (&manager, &QNetworkAccessManager::finished, this , &HttpsClient::onFinished); connect (&manager, &QNetworkAccessManager::sslErrors, this , &HttpsClient::onSslErrors); } void HttpsClient::sendMessage (const QUrl &url, const QString &message) { QNetworkRequest request (url) ; request.setHeader (QNetworkRequest::ContentTypeHeader, "text/plain" ); QSslConfiguration sslConfig = QSslConfiguration::defaultConfiguration (); sslConfig.setPeerVerifyMode (QSslSocket::VerifyNone); request.setSslConfiguration (sslConfig); manager.post (request, message.toUtf8 ()); } void HttpsClient::onFinished (QNetworkReply *reply) { int statusCode = reply->attribute (QNetworkRequest::HttpStatusCodeAttribute).toInt (); QString reason = reply->attribute (QNetworkRequest::HttpReasonPhraseAttribute).toString (); QByteArray body = reply->readAll (); qDebug () << "HTTP Status:" << statusCode << reason; qDebug () << "Response body:" << QString::fromUtf8 (body); reply->deleteLater (); } void HttpsClient::onSslErrors (QNetworkReply *reply, const QList<QSslError> &errors) { qWarning () << "SSL Errors:" << errors; reply->ignoreSslErrors (); }
4️⃣ main.cpp
服务端
1 2 3 4 5 6 7 8 9 #include <QCoreApplication> #include "httpsserver.h" int main (int argc, char *argv[]) { QCoreApplication a (argc, argv) ; HttpsServer server; return a.exec (); }
客户端
1 2 3 4 5 6 7 8 9 10 #include <QCoreApplication> #include "httpsclient.h" int main (int argc, char *argv[]) { QCoreApplication a (argc, argv) ; HttpsClient client; client.sendMessage (QUrl ("https://127.0.0.1:8443" ), "Hello over HTTPS!" ); return a.exec (); }
运行说明
先运行 服务端 (会监听 8443 端口)
再运行 客户端 (会通过 HTTPS 发送消息)
服务端会打印收到的消息,客户端会显示状态码和响应内容