2016-12-30 73 views
0

應該如何閱讀QLocalSocket/QDataStream?應該如何閱讀QLocalSocket/QDataStream以避免死鎖?

我有一個程序可以通過命名管道使用QLocalSocketQDataStream與另一個進行通信。下面的recieveMessage()插槽連接到QLocalSocketreadyRead()信號。

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讀取正確的方法是什麼?

回答

2

您的循環會阻止事件循環,因此如果所有沒有到達第一次讀取的數據,您將永遠無法獲取數據,這是什麼原因導致您的問題出現。

正確的做法是使用信號和插槽,這裏是信號和插槽,只讀取插槽中的可用數據,如果沒有足夠的數據,緩衝並返回,並在獲得下一個信號時讀取更多信息。

小心使用這種替代方法:如果你有絕對的把握你所期望的數據將(與你控制客戶端和服務器的本地套接字也許不是不合理的)到達及時,或者如果整個事情是在沒有別的東西的線程中,那麼可以使用waitForReadyRead方法。但事件循環將保持阻塞,直到數據到達,例如凍結GUI(如果在GUI線程中),並且通常很麻煩。

+0

謝謝,我沒有想到它是* my * loop阻塞(儘管我看到它在調試器中旋轉!)而不是readRawData()。 – sebf