为什么我在尝试将QSslSocket存储在QScopedPointer中时会出现bps_remove_fd失败?

时间:2013-05-14 08:30:06

标签: c++ qt blackberry-10 blackberry-playbook

我正在使用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。更容易。我仍然想知道上述错误的原因

1 个答案:

答案 0 :(得分:0)

我们可以查看the source code以了解正在发生的事情。 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回调和相关的用户数据也被删除。

     

[returns] BPS_SUCCESS如果fd(文件描述符)已成功从频道中移除BPS_FAILURE,否则设置了errno值。

可能导致bps_remove_fd失败的唯一线索是fd不存在的可能性,这意味着您的套接字没有任何有效的文件描述符。另一个错误可能是由于未指定的原因,文件存在但未被删除。

应该设置变量errno,所以如果你看一下,你可能会有一个更完整的错误描述 - 我没试过,我没有它需要的东西 - 。

我打赌bps_remove_fd的工作原理与POSIX的close(int fd)相同,所以我查看了close's documentation,了解可能导致失败的原因。它声明在下列情况下它可能会失败:

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

我会把这个答案作为评论,因为它在你的特定情况下并没有真正回答这个问题,但我希望它至少可以帮助你理解更多的内容:)