Я разрабатываю сетевое приложение для игровой книги 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 режиме. Гораздо проще Я все еще хотел бы знать причину вышеуказанной ошибки, однако
Мы можем взглянуть на исходный код для того, чтобы увидеть, что происходит. Исходный код 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
может быть прервано сигналом (должен выйти из строя).Я бы сделал этот ответ комментарием, поскольку он не отвечает на этот вопрос в вашем конкретном случае, но я надеюсь, что он, по крайней мере, поможет вам понять, что происходит немного больше 🙂
Других решений пока нет …