关于C#:QLocalSocket/QDataStream应该如何读取以避免死锁? | 珊瑚贝

How should QLocalSocket/QDataStream be read to avoid deadlocks?


QLocalSocket/QDataStream应该如何读取?

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

1
2
3
4
5
6
7
8
9
10
11
12
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().

如果我添加…

1
2
if (m_socket>bytesAvailable() < 5)
    return;

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

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

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


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

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

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

  • 谢谢,我没有想到这是我的循环阻塞(即使我看到它在调试器中旋转!)而不是 readRawData()。


来源:https://www.codenong.com/41397126/

微信公众号
手机浏览(小程序)

Warning: get_headers(): SSL operation failed with code 1. OpenSSL Error messages: error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed in /mydata/web/wwwshanhubei/web/wp-content/themes/shanhuke/single.php on line 57

Warning: get_headers(): Failed to enable crypto in /mydata/web/wwwshanhubei/web/wp-content/themes/shanhuke/single.php on line 57

Warning: get_headers(https://static.shanhubei.com/qrcode/qrcode_viewid_9972.jpg): failed to open stream: operation failed in /mydata/web/wwwshanhubei/web/wp-content/themes/shanhuke/single.php on line 57
0
分享到:
没有账号? 忘记密码?