0

我正在使用 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 路线走时(非 ssl 工作正常!),我最终遇到以下运行时错误:

virtual void QEventDispatcherBlackberry::unregisterSocketNotifier(QSocketNotifier*) bps_remove_fd() 失败 19

鉴于错误描述和代码在其他平台上按预期工作(在 mac 和 linux 上测试)的事实,该错误可能与黑莓相关。(注意,数字 19 指的是文件描述符)。

任何想法为什么我会看到此错误以及如何解决它?

谢谢,

本。

编辑:我刚刚意识到,在非 ssl 模式下,我可以只拥有一个 QSslSocket 并将其视为常规 QTcpSocket 而不是使用指针。容易得多。但是,我仍然想知道上述错误的原因

4

1 回答 1

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's 的文档以了解可能导致失败的原因。它声明它应该/可能在以下情况下失败:

  • 该参数不是有效的文件描述符(将失败)。
  • close可能会被信号中断(将失败)。
  • 读取或写入文件系统时发生 I/O 错误(可能失败)。

我会将此答案作为评论,因为它并没有真正回答您的特定情况下的问题,但我希望它至少可以帮助您进一步了解正在发生的事情:)

于 2013-05-15T09:27:25.410 回答