gpt4 book ai didi

c++ - 简单 QSsl 客户端/服务器 : cannot start handshake on non-plain connection

转载 作者:行者123 更新时间:2023-11-28 07:44:05 24 4
gpt4 key购买 nike

我尝试在 QtNetwork 中的客户端和服务器之间创建一个简单的 ssl 连接。

但是我有一个问题。首先我运行服务器。然后我运行客户端。当我第一次运行客户端时没有任何反应,但是当我第二次运行它时我得到了QSslSocket::startServerEncryption: cannot start handshake on non-plain connection。我不知道如何修复它。

这是服务器:

//server.h

#ifndef SERVER_H
#define SERVER_H

#include <QtNetwork>
#include <QObject>
#include <QTcpServer>
#include <QTcpSocket>
#include <QSslSocket>

class Server: public QTcpServer
{
Q_OBJECT

public:
Server(QObject * parent = 0);
void incomingConnection(int handle);
~Server();

public slots:
void startRead();

private:
QSslSocket* socket;
};

#endif // SERVER_H

服务器源文件:

//server.cpp

#include "server.h"
#include <iostream>
#include <QByteArray>
#include <QSslCertificate>
#include <QSslKey>
using namespace std;

Server::Server(QObject* parent) :
QTcpServer(parent)
{
socket = new QSslSocket;

connect(socket, SIGNAL(encrypted()),
this, SLOT(startRead()));

listen(QHostAddress::Any, 8889);
}

void Server::startRead()
{
char buffer[1024] = { 0 };
socket->read(buffer, socket->bytesAvailable());
cout << buffer << endl;
socket->close();
}

void Server::incomingConnection(int socketDescriptor)
{
if (socket->setSocketDescriptor(socketDescriptor))
{
connect(socket, SIGNAL(encrypted()),
this, SLOT(startRead()));

QByteArray key;
QByteArray cert;

QFile file_key("/path_to_key/rsakey");

if(file_key.open(QIODevice::ReadOnly))
{
key = file_key.readAll();
file_key.close();
}
else
{
qDebug() << file_key.errorString();
}

QFile file_cert("/path_to_certificate/mycert.pem");
if(file_cert.open(QIODevice::ReadOnly))
{
cert = file_cert.readAll();
file_cert.close();
}
else
{
qDebug() << file_cert.errorString();
}

QSslKey ssl_key(key, QSsl::Rsa);
QSslCertificate ssl_cert(cert);

socket->setPrivateKey(ssl_key);
socket->setLocalCertificate(ssl_cert);

QSslConfiguration cfg = socket->sslConfiguration();
cfg.caCertificates();

socket->startServerEncryption();
}
}

Server::~Server()
{
delete socket;
}

服务器主文件:

//server main

#include "server.h"
#include <QCoreApplication>

int main(int argc, char** argv)
{
QCoreApplication app(argc, argv);

Server server;

return app.exec();
}

这是客户端:

//client.h
#ifndef CLIENT_H
#define CLIENT_H

#include <QtNetwork>
#include <QObject>
#include <QString>
#include <QSslSocket>

class Client: public QObject
{
Q_OBJECT

public:
Client(QObject* parent = 0);
~Client();
void start(QString address, quint16 port);

public slots:
void startTransfer();

private:
QSslSocket client;
};


#endif // CLIENT_H

客户端源文件:

// client.cpp

#include "client.h"
#include <QDebug>

Client::Client(QObject* parent) :
QObject(parent)
{
connect(&client, SIGNAL(encrypted()),
this, SLOT(startTransfer()));
}

Client::~Client()
{
client.close();
}

void Client::start(QString address, quint16 port)
{
client.connectToHostEncrypted(address, port);
}

void Client::startTransfer()
{
qDebug() << "startTransfer()";
client.write("Hello, world", 13);
}

客户端主文件:

//client main

#include "client.h"
#include <QCoreApplication>

int main(int argc, char** argv)
{
QCoreApplication app(argc, argv);

Client client;
client.start("127.0.0.1", 8889);

return app.exec();
}

谁能告诉我缺少什么?

最佳答案

这里的问题是 QSslSocket 不能被重用(我打开了一个关于这个的错误 QTBUG-59348 ),所以一旦你第二次调用 setSocketDescriptor (一旦一个新的连接到达)内部模式就处于加密状态。

您的代码还有一个问题,即使 QSslSocket 可以重用,您在构造函数中创建了一个套接字,因此您一次只能接受一个连接。您必须在 incommingConnection 中创建一个新的 QSslSocket,如果您有 QTcpServer 的实现,则不需要调用 nextPendingConnection(),如果您这样做,您将得到两个指向同一个 FD 的对象,一个 QTcpSocket 和一个 QSsqSocket 创建由你。

关于c++ - 简单 QSsl 客户端/服务器 : cannot start handshake on non-plain connection,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15213139/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com