我正在使用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。更容易。我仍然想知道上述错误的原因
答案 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
可能会被信号中断(必须失败)。我会把这个答案作为评论,因为它在你的特定情况下并没有真正回答这个问题,但我希望它至少可以帮助你理解更多的内容:)