Почему я получаю ошибку bps_remove_fd при попытке сохранить QSslSocket внутри QScopedPointer?

Я разрабатываю сетевое приложение для игровой книги Blackberry с использованием Qt4.8.3, часть которого включает в себя хранение QAbstractSocket в QScopedPointer следующим образом:

QScopedPointer<QAbstractSocket> nntp;

В моей реализации я сохраняю либо QSslSocket, либо QTcpSocket (оба из которых наследуются от QAbstractSocket) в зависимости от того, должно ли шифрование соединения, т.е.

if(ssl) {
nntp.reset(new QSslSocket(this));
(dynamic_cast<QSslSocket*>(nntp.data())))->connectToHostEncrypted(server, port);
} else {
nntp.reset(new QTcpSocket(this));
nntp->connectToHost(server, port);
}

При переходе по маршруту ssl (non-ssl работает отлично!) Я получаю следующую ошибку во время выполнения:

виртуальная пустота QEventDispatcherBlackberry :: unregisterSocketNotifier (QSocketNotifier *) bps_remove_fd () завершилась ошибкой 19

Ошибка, вероятно, связана с blackberry, учитывая описание ошибки и тот факт, что код работает должным образом на других платформах (протестировано на mac и linux). (Обратите внимание, номер 19 относится к дескриптору файла).

Любые идеи, почему я вижу эту ошибку и как я могу это исправить?

Спасибо,

Бен.

РЕДАКТИРОВАТЬ: я только что понял, что вместо использования указателя, я могу просто иметь один QSslSocket и рассматривать его как обычный QTcpSocket, когда в не-ssl режиме. Гораздо проще Я все еще хотел бы знать причину вышеуказанной ошибки, однако

0

Решение

Мы можем взглянуть на исходный код для того, чтобы увидеть, что происходит. Исходный код unregisterSocketNotifier является:

void QEventDispatcherBlackberry::unregisterSocketNotifier(QSocketNotifier *notifier)
{
// Unregister the fd with bps
int sockfd = notifier->socket();
int result = bps_remove_fd(sockfd);
if (result != BPS_SUCCESS)
qWarning() << Q_FUNC_INFO << "bps_remove_fd() failed";

// Allow the base Unix implementation to unregister the fd too
QEventDispatcherUNIX::unregisterSocketNotifier(notifier);
}

И сделать корреляцию с bps_remove_fd документация, которая гласит:

Если дескриптор файла присутствует, он удаляется из канала. Обратный вызов io_handler и связанные пользовательские данные также удаляются.

[Возвращает] BPS_SUCCESS если fd (дескриптор файла) был успешно удален из канала, BPS_FAILURE со значением errno, установленным в противном случае.

Единственные подсказки о том, что можно сделать bps_remove_fd неудачей являются вероятность того, что fd отсутствует, что означает, что у вашего сокета нет допустимого файлового дескриптора. Другая ошибка может заключаться в том, что по какой-либо причине не указан файл существует, но не удаляется.

Переменная errno должен быть установлен, чтобы вы могли иметь более полное описание ошибки, если вы посмотрите на него — я не пробовал, хотя, у меня нет того, что нужно -.

держу пари bps_remove_fd работает по тому же принципу, что и POSIX close(int fd)так что я взглянул на closeдокументация чтобы увидеть, что может вызвать сбой. В нем говорится, что он может / может потерпеть неудачу в следующих случаях:

  • Аргумент не является допустимым файловым дескриптором (должен потерпеть неудачу).
  • close может быть прервано сигналом (должен выйти из строя).
  • Произошла ошибка ввода-вывода при чтении или записи в файловую систему (может произойти сбой).

Я бы сделал этот ответ комментарием, поскольку он не отвечает на этот вопрос в вашем конкретном случае, но я надеюсь, что он, по крайней мере, поможет вам понять, что происходит немного больше 🙂

0

Другие решения

Других решений пока нет …