首页 > 解决方案 > 如何使用阻塞套接字 API 添加消息发送操作 (smtp) 的进度?

问题描述

我正在使用阻塞套接字 API(waitFor* 函数)通过​​ smtp 协议(它是一个 DLL 模块)发送邮件。所有操作都是同步的:connect->waitForConnected(timeout)->login->waitForReadyRead(timeout)->sendMessage->waitForBytesWritten(timeout)->等。我正在使用阻塞 API,因为QCoreApplication需要缺席(不同应用程序使用的 DLL,包括非基于 qt 的)。阻塞函数不需要事件循环,它工作正常。但是,我如何才能对长期发送邮件操作(例如,带有大附件)进行可视化处理?以及如何在sendmailDLL 中组织进度通知的回调?ps:所有标记为函数的阻塞 waitFor* 函数,在 Windows 上可能会随机失败。readyRead()如果您的软件将在 Windows 上运行,请考虑使用事件循环和信号。为什么?

标签: c++qtsocketssmtpqtnetwork

解决方案


使用 DLL 时绝对可以有一个QApplication实例(一定QApplication不是QCoreApplication,因为您需要基于小部件的 gui)。它集成到主线程的本机消息循环中。请记住,要运行 Qt Gui,您只需要一个本机事件循环 - 代码不必停留在QCoreApplication::exec. 您需要一个应用程序实例,并且需要通过调用exec一次来启动它,并确保它返回(即通过使用零超时计时器),但仅此而已。除此之外,应用程序的主线程的消息泵将为您处理事情。

此外,要使用网络 API,您不需要卡在主线程中 - 您可以在单独的线程中处理它们。

您的 DLL 将与不在主线程中运行消息泵的控制台应用程序不兼容,但是您可以作弊:在 Windows 上,并且仅在 Windows 上,theQCoreApplication及其派生类可以在任何线程中使用:)

绝对必须将 DLL 与 Qt 静态链接,或者使用放在唯一命名空间中的动态链接 Qt。请记住,如果您链​​接的应用程序使用 Qt,则绝对不能保证他们构建的 Qt 与您使用的 Qt 二进制兼容。哪怕是同一个版本。


推荐阅读