根据客户需求,写了一个小的通讯软件,用于与上游服务器通讯。采用的是Https协议。
通用写法及问题描述
通讯软件在自己电脑上可运行,但是在客户电脑上就无法正常运行。总是显示连接不上,日志打印后,会出现“QSslSocket::connectToHostEncrypted: TLS initialization failed”的报错。代码通用部分写法精简如下:
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{
QNetworkAccessManager* pManager = new QNetworkAccessManager(this);
QNetworkRequest request;
QUrl url = ui->lineIPServer->text();
request.setUrl(QUrl(url));
request.setHeader(QNetworkRequest::ContentTypeHeader,"application/json; charset=utf-8");
QString jsonToSever = "xxxxxx";
QString strSendToSercer = QString("{\"dataList\": %1}").arg(jsonToSever);
QByteArray bytePost = strSendToSercer.toUtf8();
QNetworkReply *pReply = pManager->post(request, bytePost);
connect(pReply, &QNetworkReply::finished, this, &MainWindow::onFinished);
}
void MainWindow::onFinished()
{
qDebug() << "server return";
QNetworkReply *pReply = qobject_cast<QNetworkReply*>(sender());
// <1>判断有没有错误
if (pReply->error()){
//输出错误码及错误信息
qDebug()<< pReply->errorString();
ui->txtSended->append(QStringLiteral("服务器无返回数据,正尝试重新上传。。。"));
pReply->deleteLater();
pReply = nullptr;
return;
}
// <2>检测状态码
int statusCode = pReply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
qDebug() << "statusCode:" << statusCode;
// <3>状态码正常,服务器成功响应本次请求
if (statusCode >= 200 && statusCode <300){
//读取返回的数据并刷新显示
QByteArray replyContent = pReply->readAll();
QTextCodec *codec = QTextCodec::codecForName("utf8");
QString all = codec->toUnicode(replyContent);
qDebug() << all;
ui->txtSended->append(all);
// 数据读取完成之后,清除reply
pReply->deleteLater();
pReply = nullptr;
}
}
原因分析:
之前biying搜了一下,大多数是在打包后的程序里放入D:\QT\Tools\mingw810_64\opt\bin目录下的两个动态库ssleay32.dll和libeay32.dll,解决了问题。但是我试了却怎么也行不通。本人使用的QT版本为5.15.2。
解决方案:
后来在QT的Tools目录下发现了OpenSSL文件夹。
点进去将其中的libcrypto-1_1-x64.dll和libssl-1_1-x64.dll,放在exe根目录下运行,就可以正常接收服务器返回数据。搞定!
个人猜想,可能是因为本人采用的编译器是msvc2019。再加上QT版本较新,原先的ssleay32.dll和libeay32.dll已经不再适用了。
QT的HTTPS写法参考链接链接: https://zhuanlan.zhihu.com/p/349171758