需要创建一个使用SSL连接到客户端的小型服务器应用程序。一次只能连接一个客户端。
客户端每次尝试建立新连接时,都会调用以下功能
void Control::on_newConnection(){
if (socket != nullptr) return;
logger.appendStandard("New connection received 0");
// New connection is available.
socket = (QSslSocket*)(listener->nextPendingConnection());
logger.appendStandard("New connection received 1");
if (!socket->isValid()) {
logger.appendError("ERROR: Could not cast incomming socket connection");
return;
}
logger.appendStandard("New connection received 2");
// Doing the connections.
connect(socket,SIGNAL(encrypted()),this,SLOT(on_encryptedSuccess()));
connect(socket,SIGNAL(sslErrors(QList<QSslError>)),this,SLOT(on_sslErrors(QList<QSslError>)));
connect(socket,SIGNAL(stateChanged(QAbstractSocket::SocketState)),this,SLOT(on_socketStateChanged(QAbstractSocket::SocketState)));
connect(socket,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(on_socketError(QAbstractSocket::SocketError)));
connect(socket,&QSslSocket::readyRead,this,&Control::on_readyRead);
connect(socket,&QSslSocket::disconnected,this,&Control::on_disconnected);
logger.appendStandard("New connection received 3");
// The SSL procedure.
socket->setPrivateKey(":/certificates/server.key");
logger.appendStandard("New connection received 3.1");
socket->setLocalCertificate(":/certificates/server.csr");
logger.appendStandard("New connection received 3.2");
socket->setPeerVerifyMode(QSslSocket::VerifyNone);
logger.appendStandard("New connection received 3.2");
socket->startServerEncryption();
logger.appendStandard("New connection received 4");
}
服务器是一个正在运行的应用程序,用于监听连接。建立连接后,我将根据客户端的要求进行处理,然后使用此功能删除连接。
void Control::clearSocket(const QString &fromWhere){
if (socket != nullptr){
logger.appendStandard(fromWhere + ": About to delete socket");
delete socket;
socket = nullptr;
logger.appendStandard(fromWhere + ": Socket deleted!");
}
}
这在客户端第一次发出请求时非常有效。建立连接后,服务器接收请求,客户端接收答案,然后在客户端关闭服务器时删除服务器中的连接。
但是,当我第二次要执行完全相同的事务时,服务器程序在此行崩溃:
socket->setLocalCertificate(":/certificates/server.csr");
由于日志消息,我知道这一点。
有人知道为什么会这样吗?
答案 0 :(得分:0)
事件队列中与基于QObject的已删除套接字对象相关的某些事件可能导致崩溃。
要安全删除,请使用socket->deleteLater()而不是直接调用delete。它计划通过事件循环删除该对象,并且该对象的所有未决事件将从事件队列中删除。