【发布时间】:2013-08-28 18:01:12
【问题描述】:
我真的很难过,希望有人知道我的问题。
我有一个非常简单的 SSL 客户端和服务器。连接很好。沟通很好。当客户端与服务器断开连接时,就会出现问题。这会在服务器上触发一个信号,该信号在 SLOT error_handler(QAbstractSocket::SocketError in_error) 中处理。我想,在那个函数中,sslSocket 对象必须被删除。
但是这样做会导致服务器出现段错误。我不明白发生了什么事。我希望这真的很简单,但显然我错过了一些 Qt(或其他)概念。
有人可以帮忙吗?
基本服务器代码:
void SSLServer::incomingConnection(int sd)
{
sslSocket = new SSLSocket(this);
if( sslSocket->setSocketDescriptor(sd))
{
QFile sslkeyfile(privKey_);
sslSocket->setPrivateKey(QSslKey(sslkeyfile.readAll(),QSsl::Rsa));
QFile cliCertFile(serverCert_);
sslSocket->setLocalCertificate(QSslCertificate(cliCertFile.readAll()));
QFile certFile(caCert_);
sslSocket->addCaCertificate(QSslCertificate(certFile.readAll()));
sslSocket->setPeerVerifyMode(QSslSocket::VerifyPeer);
sslSocket->setProtocol(QSsl::SslV3);
connect(sslSocket, SIGNAL(error(QAbstractSocket::SocketError)),
this, SLOT(error_handler(QAbstractSocket::SocketError)));
connect(sslSocket, SIGNAL(sslErrors(QList<QSslError>)),
this, SLOT(ssl_error_handler(QList<QSslError>)));
connect(sslSocket, SIGNAL(encrypted()), this,
SLOT(ready()));
connect(sslSocket, SIGNAL(readyRead()), this,
SLOT(read_data_from_client()));
sslSocket->startServerEncryption();
if(!sslSocket->waitForEncrypted())
{
qDebug() << "failed to perform SSL handshake with client";
return;
}
}
}
void SSLServer::read_data_from_client()
{
QByteArray qstrbytes = sslSocket->readAll();
qDebug() << Q_FUNC_INFO << qstrbytes;
}
void SSLServer::ready()
{
QSslCertificate clientCert = sslSocket->peerCertificate();
qDebug() << clientCert.isValid();
}
void SSLServer::error_handler(QAbstractSocket::SocketError in_error)
{
qDebug() << Q_FUNC_INFO << in_error;
if(in_error == QAbstractSocket::RemoteHostClosedError)
{
delete sslSocket; //// line causes crash !!!!!!
}
}
【问题讨论】:
-
您正在删除正在调用错误处理程序的对象。这可不好。
-
我是??错误处理程序是“this”的成员,它是 SSLServer 对象。那不是我要删除的内容。 sslSocket 对象是我要删除的对象。它伴随着联系来来去去。 SSLServer 对象在程序期间存在。我是不是误解了你所说的某些内容?谢谢。
-
您已将
sslSocket的信号连接到该插槽。发射器是调用插槽的人(无论如何都是直接连接)。即,一旦您的插槽完成,代码会流回 sslSocket 代码中的某个位置,并删除this。这很糟糕。 -
啊,我认为这是有道理的。谢谢。我将相应地修改我的代码,看看它在哪里。如果我发现有用的东西,请告诉你。