如果我想将数据写入远端并等待其应答,我至少需要一个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,那么不,你不应该被要求在调用waitForReadyRead
时调用waitForBytesWritten
。
在非同步设备的情况下,将需要。
我随后问了Thiago Macieira (QtCore维护者)关于这个主题,他回答说,对于QAbstractSocket, waitForBytesWritten和waitForReadyRead都将写入待处理的字节,这些字节坐在qt缓冲区中等待被移交给操作系统。
如果远程站点因为等待另一方(本地)读取数据而阻塞,那么只等待写入字节,然后再读取传入字节的应用程序可能会死锁。由于远端阻塞,它无法读取本地发送的数据。因此,如果本地端写得太多,导致阻塞,那么每一方都将等待另一方读取它们的数据并死锁。因此,bytesWritten和readyRead等待函数都处理qt读和qt写缓冲区。waitForBytesWritten甚至可能发出readyRead信号,这是我没有预料到的。所以waitForBytesWritten调用本质上是多余的,可以删除。