首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >QTcpSocket读取错误

QTcpSocket读取错误
EN

Stack Overflow用户
提问于 2014-08-14 00:34:55
回答 3查看 1.9K关注 0票数 0

我有一个基于Qt的TCP客户端和服务器,使用QTcpServer和QTcpSocket类进行通信。服务器端使用Qt 5.3.1编译,客户端使用Qt 4.8.1编译。这样做是因为客户端是使用运行在Ubuntu 12.04上的Qt 4.8.1的框架的一部分。

由于我使用的类在两个Qt版本中都可用,所以我认为这不会造成问题。

然而,我的客户机有一些奇怪的问题,它不能从服务器接收数据!我检查了服务器端,数据是从服务器发送的,我还可以使用wireshark查看网络上的数据包。然而,在我的客户机代码中,数据没有到达!

我对此进行了一些调查,得出了一个奇怪的结论:只有在使用QTcpSocket的read方法时才会发生这种情况!如果我使用本地POSIX read系统调用,我就能够正确地读取数据!下面是我的代码:

代码语言:javascript
复制
qDebug() << "QTcpSocket::bytesAvailable() gives" << m_pSocket->bytesAvailable();

char nData;

qint32 szReceived;

if(sizeof(char) != (szReceived = m_pSocket->read((char*)&nData,sizeof(char))))
{
    qDebug() << "Error reading data from QTcpSocket::read()" << m_pSocket->errorString();
}
else
{
    qDebug() << "QTcpSocket::read() returned" << szReceived;
}

int nDesc = m_pSocket->socketDescriptor();

if(sizeof(char) != (szReceived = read(nDesc, &nData,sizeof(char))))
{
    perror("Error reading data from POSIX read()");
}
else
{
    qDebug() << "POSIX read() returned" << szReceived;
}

这将生成以下输出:

代码语言:javascript
复制
QTcpSocket::bytesAvailable() gives 0 
Error reading data from QTcpSocket::read() "Network operation timed out" 
POSIX read() returned 1

为什么POSIX系统调用按预期读取缓冲的数据,而Qt类无法读取它?另外,我没有设置任何套接字选项,所以我不知道为什么它会报告网络操作超时的错误!

EN

回答 3

Stack Overflow用户

发布于 2014-08-14 00:57:37

"read“是POSIX中的阻塞调用,它等待数据到达。虽然QTcpSocket是非阻塞操作,但它会立即返回缓冲的数据。在进行读取之前调用waitForReadyRead

代码语言:javascript
复制
 socket->waitForReadyRead();
 if(sizeof(char) != (szReceived = m_pSocket->read((char*)&nData,sizeof(char))))
票数 1
EN

Stack Overflow用户

发布于 2014-08-14 01:09:07

我认为这是对QTcpSocket概念的滥用。QTcpSocket实现异步体系结构,而POSIX读/写调用被阻塞,直到套接字上的I/O成功或错误。对于readyRead信号,最好是在时隙中进行读操作。请考虑以下内容:

代码语言:javascript
复制
class MyClient
{
  Q_OBJECT

...

private slots:

  readFromSocket();

};

在您的初始化中:

代码语言:javascript
复制
QObject::connect(
        m_pSocket, SIGNAL(readyRead()),
        this, SLOT(readFromSocket()));

真正的工作已经完成了:

代码语言:javascript
复制
void
MyClient::readFromSocket()
{
  QByteArray buffer = m_pSocket->readAll();
  // All your data in buffer. 
}
票数 0
EN

Stack Overflow用户

发布于 2014-08-18 19:19:52

我知道QTcpSocket的非阻塞特性和POSIX read调用的阻塞特性。不幸的是,我不能使用信号readFromSocket,因为我的通信体系结构希望在每次通信(TCP way)之前发送一个报头,以查看为该特定消息流式传输的有效负载。因此,我必须等待,直到我至少收到报头。

我确实认为这与模式(阻塞或非阻塞)有关。我又做了一些测试,没有一个是确凿的。在我的一个测试中,我尝试调用一个超时为1ms、2ms、3ms的waitForReadyRead。这仍然不足以使读取成功!我怀疑读取是否需要这样的时间才能从内核缓冲区读取到用户空间,因为我可以从wireshark清楚地看到,消息是在400ms内收到的。

当我给出-1作为waitForReadyRead的超时值时,读取成功!换句话说,只有当套接字无限期等待时,读取才会成功,就像POSIX读取调用的情况一样。

我观察到的另一件奇怪的事情是,这个问题最初是在我运行使用Qt 5.3.1编译的服务器和使用Qt 4.8.1编译的客户端时发现的。当我编译我的客户端使用Qt 5.3.1时,我没有看到这个问题!我甚至尝试过使用Qt 4.7.1进行编译,没有任何问题!

Qt 4.8.1的套接字实现有什么已知的问题吗?不幸的是,我找不到太多关于这方面的信息。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25291563

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档