众所周知,QTcpSocket中的write和read函数是异步的,也就是非阻塞的。如果我们需要同步读写,就必须用QT为我们提供的waitForConnected、 waitForDisconnected、waitForBytesWritten、waitForReadyRead这四个函数。这看起来是一件很完美的事情,然而,QT文档中对waitFor系列函数有这样一句描述:
Note: This function may fail randomly on Windows.
是的,waitFor系列函数在Windows系统上可能会发生随机错误,这无疑是一件很让人无语的事情。幸运的是,QT文档在之后给出了解决方案:我们可以利用EventLoop和QTcpSocket类中的connected() 、disconnected() 、bytesWritten()、readyRead() 四个信号来分别实现上述四个函数。下面给出的是用QEventLoop类和bytesWritten()实现的类似于waitForBytesWritten函数的功能:
QEventLoop loop;
connect(m_socket, &MySocket::loopStopSignal, &loop, &QEventLoop::quit);
QString request = QString("wdnmd");
socket->write(request.toUtf8().data());
loop.exec();
MySocket类继承于QTcpSocket类,m_socket是MySocket类的一个实例。我们还要在MySocket类中定义一个槽函数loopStopSlot,然后在MySocket类的构造函数中把bytesWritten信号与loopStopSlot绑定:
void MySocket::loopStopSlot(qint64 bytes)
{
emit loopStopSignal();
}
//这段代码写在构造函数中
connect(this, &MySocket::bytesWritten, this, &MySocket::loopStopSlot);
其余三个函数的实现方式同理。
另外不要忘了加上 QEventLoop的头文件。
以上代码仅在QT5上测试过。