libQtShadowsocks
libQtShadowsocks copied to clipboard
TcpRelay 可能会过早的发出finished信号, 数据发送完毕之前被释放
我在 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对象被释放, local
和 remote
随其同时释放, 但由于local
网络速度较慢, 可能还出于ClosingState
的状态, 数据尚未发送完毕就被释放掉了
@zhaoyanliang2 如何解决stop的时候崩溃哇?