Консольное приложение Qt не работает из-за setLocalCertificate для QSslSocket - PullRequest
0 голосов
/ 11 апреля 2019

Необходимо создать небольшое серверное приложение, которое использует 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");

Я знаю это из-за сообщений журнала.

Кто-нибудь знает, почему это может происходить?

1 Ответ

0 голосов
/ 11 апреля 2019

Возможно, что-то в очереди событий, связанное с удаленным объектом сокета на основе QObject, вызывает сбой.

Для безопасного удаления используйте socket-> deleteLater () вместо прямого вызова delete.Он планирует удаление объекта через цикл событий, и все ожидающие события для объекта будут удалены из очереди событий.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...