この質問は興味深いので、いくつか調べてみましょう。キープアライブ タイムアウトを大きく設定して 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
. そこで、( Window → Views → Debugger log
Qt Creator で) デバッガー コンソールを開き、プロセスが一時停止している間にブレークポイントを追加しました。
bp QAbstractSocket::close
注: これは cdb (MS デバッガー) 用です。他のデバッガーには他のコマンドが必要です。別の注意: 私は Qt をデバッグ情報と共に使用していますが、このアプローチは Qt なしでは機能しない可能性があります。
2分間待った後、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
、ハードコードされています。
関連するすべてのクラスはプライベートであり、これを防ぐ方法が見つかりませんでした。そのため、キープアライブ リクエストを 1 分ごとに送信する方が簡単です (少なくとも 1 分で十分安全であることがわかります)。別の方法として、Qt コードを書き直してカスタム バージョンをコンパイルします。