fix: the deadlock issue with actively disconnected clients.

This commit is contained in:
2025-06-28 09:00:38 +08:00
parent b234ec8079
commit 3216356d66
2 changed files with 34 additions and 32 deletions

View File

@@ -11,8 +11,8 @@
| 序号 | 类型 | 内容 | 说明 | 基于版本 | 完成版本 |
| :--: | :--: | ------------------------------------------------------------ | :--: | :------: | :------: |
| 18 | 问题 | 断开后重连貌似没有发送心跳包。 | | 0.1 | |
| 17 | 问题 | 服务端主动踢出的客户端,主动重连假链接,不可用无反应。 | | 0.1 | |
| 18 | 问题 | 断开后重连貌似没有发送心跳包。 | | 0.1 | 0.2 |
| 17 | 问题 | 服务端主动踢出的客户端,主动重连假链接,不可用无反应。 | | 0.1 | 0.2 |
| 16 | 优化 | 传输完成后接收端要刷新一次。 | | 0.1 | |
| 15 | 问题 | 拖动文件夹到对方,应当不处理,并日志提示。 | | 0.1 | |
| 14 | 功能 | 文件浏览部分添加右键复制全路径功能。 | | 0.1 | |

View File

@@ -87,27 +87,6 @@ void Server::onNewConnection()
sendData(clientSocket, frame);
}
void Server::onClientDisconnected()
{
QTcpSocket* socket = qobject_cast<QTcpSocket*>(sender());
if (!socket) {
return;
}
QHostAddress peerAddress = socket->peerAddress();
quint32 ipv4 = peerAddress.toIPv4Address();
QString ipStr = QHostAddress(ipv4).toString();
QString clientId = QString("%1:%2").arg(ipStr).arg(socket->peerPort());
{
QWriteLocker locker(&rwLock_);
clients_.remove(clientId);
}
qDebug() << "Client disconnected:" << __LINE__ << clientId;
socket->deleteLater();
}
void Server::onReadyRead()
{
QTcpSocket* socket = qobject_cast<QTcpSocket*>(sender());
@@ -116,6 +95,7 @@ void Server::onReadyRead()
}
QSharedPointer<ClientInfo> client;
{
QReadLocker locker(&rwLock_);
client = clients_.value(socket->property("clientId").toString());
@@ -230,22 +210,44 @@ bool Server::sendData(QTcpSocket* socket, QSharedPointer<FrameBuffer> frame)
return socket->write(data) == data.size();
}
void Server::onClientDisconnected()
{
QTcpSocket* socket = qobject_cast<QTcpSocket*>(sender());
if (!socket) {
return;
}
QString clientId = socket->property("clientId").toString();
{
QWriteLocker locker(&rwLock_);
if (clients_.count(clientId)) {
clients_.remove(clientId);
}
}
qDebug() << "Client disconnected:" << __LINE__ << clientId;
socket->deleteLater();
}
void Server::monitorClients()
{
qint64 now = QDateTime::currentDateTime().toMSecsSinceEpoch() / 1000;
QWriteLocker locker(&rwLock_);
std::vector<QTcpSocket*> prepareRemove;
for (auto it = clients_.begin(); it != clients_.end();) {
auto t = now - it.value()->connectTime;
if (t > NO_HEATBEAT_TIMEOUT) {
qDebug() << "Disconnecting inactive client:" << it.value()->id;
it.value()->socket->disconnectFromHost();
it = clients_.erase(it);
} else {
++it;
{
QReadLocker locker(&rwLock_);
for (auto& c : clients_) {
if (now - c->connectTime > NO_HEATBEAT_TIMEOUT) {
prepareRemove.push_back(c->socket);
}
}
}
for (const auto& s : prepareRemove) {
qDebug() << "Removing inactive client:" << s->property("clientId").toString();
s->disconnectFromHost();
}
}
QByteArray Server::getClients()
{