0

QLocalSocket/QDataStream应该怎么读?

我有一个程序通过命名管道使用QLocalSocketand与另一个程序通信QDataStream。下面的recieveMessage()插槽连接到QLocalSocket'sreadyRead()信号。

void MySceneClient::receiveMessage()
{    
    qint32 msglength;
    (*m_stream) >> msglength;

    char* msgdata = new char[msglength];
    int read = 0;
    while (read < msglength) {
        read += m_stream->readRawData(&msgdata[read], msglength - read);
    }
    ...
} 

我发现应用程序有时会挂起readRawData()。也就是说,它成功读取了 4 字节的标头,但之后再也没有从readRawData().

如果我添加...

if (m_socket->bytesAvailable() < 5)
    return;

...到此功能的开始,应用程序运行良好(带有简短的测试消息)。

我当时猜测(文档非常稀少)发生了某种死锁,我必须使用bytesAvailable()信号来逐渐建立缓冲区而不是阻塞。

为什么是这样?从 QLocalSocket 读取的正确方法是什么?

4

1 回答 1

2

您的循环阻止了事件循环,因此如果所有数据都没有到达 pn 首次读取,您将永远不会获得数据,这就是我认为导致您的问题的原因。

正确的做法是使用信号和槽,readyRead这里使用-signal,只读取你的槽中可用的数据,如果不够,缓冲返回,得到下一个信号时再读取。

小心这种替代方法: 如果您绝对确定您期望的所有数据都会迅速到达(对于您控制客户端和服务器的本地套接字可能不是不合理的),或者如果整个事情都在一个线程中没有别的,那么使用waitForReadyRead方法可能就可以了。但是事件循环将保持阻塞直到数据到达,例如冻结 GUI(如果在 GUI 线程中),并且通常很麻烦。

于 2016-12-30T13:54:24.180 回答