如果我想将数据写入远程端并等待它的回答,我至少需要一个waitForReadyRead
. 但在调用它之前,我是否需要使用 手动刷新输出队列waitForBytesWritten
,还是 Qt 会自动为我刷新写入队列?我正在同步操作(阻塞),因此在这个函数中我无法使用事件循环或本地事件循环。
使用 时std::cin
,我们可以确定之前写入的字节std::cout
将被刷新。这就是类似的情况——它也适用于 Qt 套接字吗?
如果我想将数据写入远程端并等待它的回答,我至少需要一个waitForReadyRead
. 但在调用它之前,我是否需要使用 手动刷新输出队列waitForBytesWritten
,还是 Qt 会自动为我刷新写入队列?我正在同步操作(阻塞),因此在这个函数中我无法使用事件循环或本地事件循环。
使用 时std::cin
,我们可以确定之前写入的字节std::cout
将被刷新。这就是类似的情况——它也适用于 Qt 套接字吗?
如果您查看源代码,作为一个抽象基类,QIODevice 在 waitForReadyRead 中做的很少,它取决于继承类的实现:
bool QIODevice::waitForReadyRead(int msecs)
{
Q_UNUSED(msecs);
return false;
}
它也适用于 Qt 套接字吗?
正如您所说,您正在同步操作,我假设您选择这个是有原因的,并且知道在主线程上,任何 GUI 在调用waitForReadyRead
. 通常,QIODevice 的异步使用是首选,Qt 是一个事件驱动的框架。
但是,Qt 文档状态:
QIODevice 的某些子类,例如 QTcpSocket 和 QProcess,是异步的。
因此,如果你的 QIODevice 是 QTcpSocket 之类的套接字,那么不,你不应该waitForBytesWritten
在调用waitForReadyRead
.
在非同步设备的情况下,它是必需的。
我随后向 Thiago Macieira(QtCore 维护者)询问了该主题,他回答说对于 QAbstractSocket,waitForBytesWritten 和 waitForReadyRead 都会写入位于 qt 缓冲区中等待移交给操作系统的待处理字节。
如果远程站点由于等待另一端(本地)读取数据而被阻塞,则仅等待写入字节然后才读取传入字节的应用程序可能会出现死锁。由于远程端阻塞,它无法读取本地端发送的数据。因此,如果本地写入太多以至于它也阻塞,每个将等待对方读取他们的数据并死锁。
因此 bytesWritten 和 readyRead 等待函数都处理 qt read 和 qt write 缓冲区。waitForBytesWritten 甚至可能会发出 readyRead 信号,这是我没想到的。所以 waitForBytesWritten 调用本质上是多余的,可以删除。