【问题标题】:'Memory Full' while transferring large file using QTcpSocket使用 QTcpSocket 传输大文件时出现“内存已满”
【发布时间】:2012-12-16 09:32:40
【问题描述】:

我正在尝试通过将bytesWritten 连接到我的函数sendNextBlock,以非阻塞方式传输一个大文件。

void AsynchronousRetrieveCommand::start()
{
    connect(socket(), SIGNAL(bytesWritten(qint64)), this, SLOT(sendNextBlock()));
    sendNextBlock();
}

void AsynchronousRetrieveCommand::sendNextBlock()
{
    socket->write(file->read(64*1024));
}

我在 Symbian 手机上运行此代码,在传输了 5-6 兆字节后,我在手机中收到“内存已满”消息框,并且在调试输出中显示此消息:

[Qt Message] CActiveScheduler::RunIfReady() returned error: -4

我认为这是某种内存泄漏,但在我的代码中看不到是什么原因造成的。

【问题讨论】:

  • 您发送的文件有多大?
  • 大约 500 MB,但仅传输了 5 MB 后发生错误。不过反正应该没关系,因为我是逐块发送的,每个块只有64k。

标签: c++ qt memory-leaks qtcpsocket


【解决方案1】:

好的,事实证明套接字的缓冲区正在不受控制地增长,因为数据被提供给它的速度比它被刷新的速度要快。

我通过检查bytesWritten 给出的值解决了这个问题,并且只写入了这么多字节(实际上,将缓冲区重新填充回 64k)。

我的固定代码现在看起来像这样:

void AsynchronousRetrieveCommand::start()
{
    connect(socket(), SIGNAL(bytesWritten(qint64)), this, SLOT(sendNextBlock(qint64)));
    sendNextBlock(64*1024);
}

void AsynchronousRetrieveCommand::sendNextBlock(qint64 bytes)
{
    socket()->write(file->read(bytes));
}

【讨论】:

  • 您缺少一些错误处理,最好使用读/写的 (char*, qint64) 重载,并检查返回值以确保数据被实际读/写。
  • 我假设如果我无法读取该文件,那么 QFile::open 将首先失败(我对此进行了检查)
  • read/write((const) char*, qint64) 返回读/写的字节数。不检查返回值会导致数据丢失。另外,打开文件后,读/写仍然会失败(然后返回-1)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-01-13
  • 2021-09-05
  • 2018-05-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-13
相关资源
最近更新 更多