QTcpSocket读取错误
QTcpSocket Read Error
我有一个基于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系统调用,我就能够正确读取数据!请看下面我的代码:
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;
}
这会产生以下输出:
QTcpSocket::bytesAvailable() gives 0
Error reading data from QTcpSocket::read() "Network operation timed out"
POSIX read() returned 1
它是如何POSIX系统调用读取缓冲数据的预期和Qt类不能读取它?另外,我没有设置任何套接字选项,所以我不知道为什么它报告一个错误,网络操作超时!
"read"在POSIX中是一个阻塞调用,它等待数据到达。当QTcpSocket是非阻塞操作时,它立即返回缓冲的数据。在执行读取操作之前调用waitForReadyRead
socket->waitForReadyRead();
if(sizeof(char) != (szReceived = m_pSocket->read((char*)&nData,sizeof(char))))
我认为这是滥用QTcpSocket概念。QTcpSocket实现异步架构,而POSIX读/写调用被阻塞,直到I/O在套接字上成功或错误。对于readyRead信号,在slot中处理read要好得多。想想看:
class MyClient
{
Q_OBJECT
...
private slots:
readFromSocket();
};
初始化:
QObject::connect(
m_pSocket, SIGNAL(readyRead()),
this, SLOT(readFromSocket()));
和真正的工作在这里完成:
void
MyClient::readFromSocket()
{
QByteArray buffer = m_pSocket->readAll();
// All your data in buffer.
}
我知道QTcpSocket的非阻塞性质和POSIX读调用的阻塞性质。不幸的是,我不能使用readFromSocket信号,因为我的通信架构期望在每次通信(TCP方式)之前发送一个头,以查看为该特定消息流的有效载荷。因此,我必须等待,直到我至少收到报头。
我相信这与模式(阻塞或非阻塞)有关。我又做了些检查,但都没有结论。在我的一个测试中,我尝试调用waitForReadyRead,超时时间分别为1毫秒、2毫秒和3毫秒。这仍然不足以使读取成功!我怀疑读取是否需要这么长的时间从内核缓冲区读取到用户空间,因为我可以从wireshark清楚地看到,消息是在400毫秒内收到的。
当我给出-1作为waitForReadyRead的超时值时,读取成功!换句话说,只有当套接字无限等待时,读取才会成功,就像POSIX读取调用的情况一样。
我观察到的另一个奇怪的事情是,这个问题最初是在我运行使用Qt 5.3.1编译的服务器和使用Qt 4.8.1编译的客户端时观察到的。当我编译我的客户端使用Qt 5.3.1,我没有看到这个问题!!我甚至尝试使用Qt 4.7.1编译,它没有任何问题!!
是否有任何已知的问题与Qt 4.8.1套接字实现?遗憾的是,我找不到太多关于这方面的信息。
- 分段错误 - 读取初始化指针的数组
- 在指向函数中读取变量时出现分割错误
- 读取某些文件时出现分段错误,似乎与文件大小无关
- 从对象C++中的文件读取内容时出现分段错误
- 我编写了以下代码来读取C++矩阵,然后打印其行和列.我收到此错误
- 可能的 ComputeCPP SYCL 错误读取嵌套缓冲区
- Eigen SparseLU解决错误读取访问冲突,这>m_sup_to_col被0x111011101110112
- 访问违规读取位置和错误读取字符串的错误
- libpng 错误:读取错误
- 错误读取字符到矩阵
- 分段错误读取 JSON 文件
- 斯特托克获取分段错误读取文件
- ifstream 初始化错误 - 读取字符时出错
- 读取错误-读取时无限
- 异常错误:读取位置0xDDDDDDDD时发生访问冲突
- 如何修复此错误读取位置0x00000008时发生访问冲突
- GDB:<错误读取变量>,带有 C++ 向量
- 找不到错误 读取大小 4 瓦尔格林德无效
- 分割错误读取文件
- libpng错误:读取错误(Visual Studio 2010)