Skip to content
This repository has been archived by the owner on Dec 10, 2019. It is now read-only.

TcpRelay 可能会过早的发出finished信号, 数据发送完毕之前被释放 #209

Open
zhaoyanliang2 opened this issue May 5, 2019 · 1 comment

Comments

@zhaoyanliang2
Copy link

我在 tcprelay.cpp 中发现了以下代码

void TcpRelay::close()
{
    if (stage == DESTROYED) {
        return;
    }

    local->close();
    remote->close();
    stage = DESTROYED;
    emit finished();
}

看下Qt文档对close()的描述

void QAbstractSocket::close()
Reimplemented from QIODevice::close().
Closes the I/O device for the socket and calls disconnectFromHost() to close the socket's connection.
See QIODevice::close() for a description of the actions that occur when an I/O device is closed.

close()内部调用了disconnectFromHost(), 再看文档对disconnectFromHost()的描述

void QAbstractSocket::disconnectFromHost()
Attempts to close the socket. If there is pending data waiting to be written, QAbstractSocket will enter ClosingState and wait until all data has been written. Eventually, it will enter UnconnectedState and emit the disconnected() signal.

调用disconnectFromHost()后QAbstractSocket对象如果还有没发送完的数据, 将会处于ClosingState的状态, 等待数据发送. 最终变成UnconnectedState状态.

举一个实例:
假设local网络速度较慢, remote网络速度较快, remote接收到了大量的数据, 然后remote的远端紧接着立即主动断开了连接, remote会发出error(RemoteHostClosedError)信号, 接下来是这些调用:
TcpRelay::onRemoteTcpSocketError() -> TcpRelay::close() -> TcpRelay::finished()
TcpRelay::finished()会导致TcpRelay对象被释放, localremote 随其同时释放, 但由于local网络速度较慢, 可能还出于ClosingState的状态, 数据尚未发送完毕就被释放掉了

@DaDaQingFeng
Copy link

@zhaoyanliang2 如何解决stop的时候崩溃哇?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants