gpt4 book ai didi

qt - 在 Qt 中使用 QNetworkAccessManager 的持久连接

转载 作者:行者123 更新时间:2023-12-04 10:24:30 27 4
gpt4 key购买 nike

我正在尝试使用 Qt 在客户端和远程服务器之间保持持久连接。我的服务器端很好。我在 Qt 中做我的客户端。这里我将使用 QNetworkAccessManager用于使用 get 方法请求服务器(QNetworkRequest 方法的一部分)。我将能够发送和接收请求。

但是过了一段时间(大约 2 分钟),客户端正在通知服务器,连接已通过自动发布请求而关闭。我认为 QNetworkAccessManager正在为此连接设置超时。我想保持两端之间的持久连接。

我的方法是否正确,如果不是,有人可以引导我走正确的道路吗?

最佳答案

这个问题很有趣,所以让我们做一些研究。我设置了一个具有大保活超时的 nginx 服务器,并编写了最简单的 Qt 应用程序:

QApplication a(argc, argv);
QNetworkAccessManager manager;
QNetworkRequest r(QUrl("http://myserver/"));
manager.get(r);
return a.exec();

我还使用以下命令(在 Linux 控制台中)来监视连接并检查问题是否完全重现:
watch -n 1 netstat -n -A inet

我快速浏览了 Qt 源代码,发现它使用了 QTcpSocket并在 QHttpNetworkConnectionChannel::close 中关闭它.因此,我打开了调试器控制台(Qt Creator 中的 Window → Views → Debugger log)并在进程暂停时添加了一个断点:
bp QAbstractSocket::close

注意:这是针对 cdb(MS 调试器)的,其他调试器需要其他命令。另一个注意事项:我使用带有调试信息的 Qt,如果没有它,这种方法可能无法工作。

经过两分钟的等待,我得到了 close() 的回溯。称呼!
QAbstractSocket::close  qabstractsocket.cpp 2587    0x13fe12600 
QHttpNetworkConnectionPrivate::~QHttpNetworkConnectionPrivate qhttpnetworkconnection.cpp 110 0x13fe368c4
QHttpNetworkConnectionPrivate::`scalar deleting destructor' untitled 0x13fe3db27
QScopedPointerDeleter<QObjectData>::cleanup qscopedpointer.h 62 0x140356759
QScopedPointer<QObjectData,QScopedPointerDeleter<QObjectData>>::~QScopedPointer<QObjectData,QScopedPointerDeleter<QObjectData>> qscopedpointer.h 99 0x140355700
QObject::~QObject qobject.cpp 863 0x14034b04f
QHttpNetworkConnection::~QHttpNetworkConnection qhttpnetworkconnection.cpp 1148 0x13fe35fa2
QNetworkAccessCachedHttpConnection::~QNetworkAccessCachedHttpConnection untitled 0x13fe1e644
QNetworkAccessCachedHttpConnection::`scalar deleting destructor' untitled 0x13fe1e6e7
QNetworkAccessCachedHttpConnection::dispose qhttpthreaddelegate.cpp 170 0x13fe1e89e
QNetworkAccessCache::timerEvent qnetworkaccesscache.cpp 233 0x13fd99d07
(next lines are not interesting)

负责此操作的类是 QNetworkAccessCache .它设置计时器并确保在 QNetworkAccessCache::Node::timestamp 时删除其对象。是过去。这些对象是 HTTP 连接、FTP 连接和凭据。

接下来,什么是 timestamp ?当对象被释放时,其时间戳按如下方式计算:
node->timestamp = QDateTime::currentDateTime().addSecs(ExpiryTime);

ExpiryTime = 120是硬编码的。

所有涉及的类(class)都是私有(private)的,我发现没有办法防止这种情况发生。因此,每分钟发送一次保持事件请求更简单(至少现在您知道 1 分钟就足够安全了),因为替代方法是重写 Qt 代码并编译自定义版本。

关于qt - 在 Qt 中使用 QNetworkAccessManager 的持久连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29745625/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com