1、问题背景描述
近期在做嵌入式QT应用程序与物联网平台交互。其实这个需求我在以往的工作中也做过,只不过这次的情况有些特殊。当我使用QNetworkAccessManager
向平台分别发起POST
和GET
请求时,打印错误如下:
这个问题在PC端并没有出现,而是在嵌入式平台瑞芯微RV1109
上出现了。
2、解决方案
参考了stackoverflow.com
上网友给出的解决方案:
意思是说忽略所谓的SSL
验证模式,这样的话问题就能够解决了。那么PC端为什么不会出现这个问题呢?是因为PC端之前就安装了云平台部门给的证书,因此PC端即使不加上面那几行代码也是可以正常运行的。而开发板不能校验通过的原因是因为开发板上没有权威的根证书,因此导致校验云平台的证书没有通过。
什么是SSL ?
SSL(Secure Sockets Layer 安全套接字协议),及其继任者传输层安全(Transport Layer Security,TLS)是为网络通信提供安全及数据完整性的一种安全协议。TLS与SSL在传输层与应用层之间对网络连接进行加密。
有关QT
下SSL
证书认证的三种方式:
(1)忽略校验证书
QSslConfiguration config ; config.setPeerVerifyMode(QSslSocket::VerifyNone); config.setProtocol(QSsl::TlsV1); QNetworkRequest request(req); request.setSslConfiguration(config);
(2)否允许在请求中使用HTTP管道
QNetworkRequest request ; request.setAttribute(QNetworkRequest::HttpPipeliningAllowedAttribute, true); QNetworkReply* reply = QNetworkAccessManager::createRequest(op, request, outgoingData); reply->ignoreSslErrors();
(3)手动加载证书
QSslConfiguration config ; QList<QSslCertificate> certs = QSslCertificate::fromPath("C:\\FiddlerRoot.crt"); config.setCaCertificates(certs); QNetworkRequest request(req); request.setSslConfiguration(config);
如果平台有强制要求必须认证证书的话,那么推荐第三种,手动将证书进行加载操作。
对开始请求的接口代码进行修改:
void network_manage::startRequest(QUrl url) { QFileInfo info(url.path()); QString fileName(info.fileName()); //获取文件名 if(fileName.isEmpty()) { fileName = "index.html"; } download_file = new QFile(fileName); if(!download_file->open(QIODevice::WriteOnly)) { qDebug()<<"file open error"; delete download_file; download_file = 0; return ; } /*添加对QSsl的配置处理*/ QSslConfiguration config = m_netGetRequestHead.sslConfiguration(); config.setPeerVerifyMode(QSslSocket::VerifyNone); config.setProtocol(QSsl::TlsV1SslV3); m_netGetRequestHead.setSslConfiguration(config); m_netGetRequestHead.setUrl(QUrl(url)); /*添加对QSsl的配置处理*/ /*进行GET请求,进行文件下载*/ download_reply = download_manager.get(m_netGetRequestHead); connect((QObject *)download_reply, SIGNAL(finished()),this, SLOT(DownLoad_FiLe_Finished())); connect((QObject *)download_reply, SIGNAL(readyRead()),this, SLOT(DownLoad_File_ReadyRead())); connect((QObject *)download_reply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(updateDown_Load_File_Progress(qint64,qint64))); }
接下来在嵌入式平台上,能够看到正常发起的POST和GET请求:
显示效果如下:
参考文献与引用
(N.d.). Retrieved from https://baike.baidu.com/item/ssl (N.d.). Retrieved from https://doc.qt.io/archives/qt-4.8/qnetworkrequest.html (N.d.). Retrieved from https://stackoverflow.com/questions/38379848/qnetworkaccessmanager-reset-tcp-connection (N.d.). Retrieved from https://blog.csdn.net/itjobtxq/article/details/8244509
往期精彩
如何添加APP到Buildroot里(以瑞芯微rv1126为例)
新产品立项了,作为嵌入式软件工程师该如何来开展设计工作?(个人经验分享)
手把手之如何在嵌入式Linux上运行QT应用程序(以百问网imx6ull开发板为例)