QTcpSocket中waitFor系列函数在windows上可能随机失效的解决办法

众所周知,QTcpSocket中的write和read函数是异步的,也就是非阻塞的。如果我们需要同步读写,就必须用QT为我们提供的waitForConnected、 waitForDisconnected、waitForBytesWritten、waitForReadyRead这四个函数。这看起来是一件很完美的事情,然而,QT文档中对waitFor系列函数有这样一句描述:

Note: This function may fail randomly on Windows.

是的,waitFor系列函数在Windows系统上可能会发生随机错误,这无疑是一件很让人无语的事情。幸运的是,QT文档在之后给出了解决方案:我们可以利用EventLoop和QTcpSocket类中的connected() 、disconnected() 、bytesWritten()、readyRead() 四个信号来分别实现上述四个函数。下面给出的是用QEventLoop类和bytesWritten()实现的类似于waitForBytesWritten函数的功能:

QEventLoop loop;
connect(m_socket, &MySocket::loopStopSignal, &loop, &QEventLoop::quit);
QString request = QString("wdnmd");
socket->write(request.toUtf8().data());
loop.exec();

MySocket类继承于QTcpSocket类,m_socket是MySocket类的一个实例。我们还要在MySocket类中定义一个槽函数loopStopSlot,然后在MySocket类的构造函数中把bytesWritten信号与loopStopSlot绑定:

void MySocket::loopStopSlot(qint64 bytes)
{
    emit loopStopSignal();
}
    //这段代码写在构造函数中
    connect(this, &MySocket::bytesWritten, this, &MySocket::loopStopSlot);

其余三个函数的实现方式同理。
另外不要忘了加上 QEventLoop的头文件。
以上代码仅在QT5上测试过。

  • 9
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
### 回答1: QTcpSocketread函数是用来从套接字读取数据的。该函数有两个重载版本:一个是读取指定长度的数据,另一个是读取所有可用的数据。 第一个版本的函数原型如下: qint64 QTcpSocket::read(char *data, qint64 maxSize) 其,data是一个指向缓冲区的指针,maxSize是要读取的最大字节数。该函数会尝试从套接字读取maxSize个字节的数据,并将其存储到data指向的缓冲区。如果读取成功,函数返回实际读取的字节数;如果读取失败,函数返回-1。 第二个版本的函数原型如下: QByteArray QTcpSocket::readAll() 该函数会读取套接字所有可用的数据,并将其存储到一个QByteArray对象。如果没有可用的数据,函数返回一个空的QByteArray对象。 ### 回答2: QTQTcpSocket类是一个基于TCP协议的socket通信类,它提供了一系列的方法和信号槽,可以实现客户端和服务器之间的网络通信。其重要的一个方法就是read函数,对于QTcpSocket类实例,read函数主要作用是从socket缓冲区读取数据。 read函数的原型如下: ```cpp qint64 QTcpSocket::read(char *data, qint64 maxSize); ``` 其,data为缓存区,maxSize为最大读取的字节数。read函数会返回实际读取的字节数,如果没有数据可读,则返回-1。 read函数是一个同步阻塞函数,它会在读取到maxSize字节之后自动阻塞等待,直到收到足够的数据或者发生错误。因此,在使用read函数之前,必须保证socket已连接成功,并且有数据可读。 read函数调用时需要注意以下几点: 1. 由于read函数是一个同步阻塞函数,如果读取到的数据较大,会导致主线程一直阻塞,因此应该将read函数放到独立的线程执行,或者使用QIODevice::readyRead()信号槽实现异步读取数据。 2. read函数会阻塞等待数据到来,因此在使用时必须确定已经有数据可读,否则会因等待数据而导致程序阻塞。 3. read函数读取的数据是字节流,而非字符串,因此需要在读取数据之后根据具体应用场景进行转换。 总之,QTcpSocketread函数是一个非常重要且常用的网络通信函数,在使用时需要根据具体应用场景进行调用,并注意其阻塞和异步的特性。 ### 回答3: QTcpSocketread函数是用于从套接字读取数据的函数。它有多个重载形式,可以读取指定长度的数据、直到读取到指定分隔符的数据、或者读取所有可用数据。函数的返回值是成功读取的字节数,不同的重载形式会返回不同类型的数据。 当我们需要从QTcpSocket读取数据时,可以通过以下步骤使用read函数: 1. 在连接套接字的readyRead信号,调用read函数读取数据。 2. 根据读取到的数据进行相应的处理,如显示在界面上、存储到文件等。 需要注意的是,由于网络环境的不确定性和传输过程可能出现的错误,read函数不一定能读取到完整的数据,可能需要多次读取才能获取到全部数据。因此,在使用read函数时,需要对读取过程进行循环判断,确保读取到了期望的数据。 另外,QTcpSocket也提供了一些其他的函数用于读取数据,如readAll、readLine等,这些函数都是基于read函数的封装,在特定情况下使用更加方便。需要根据具体的需求选择合适的函数,以便实现数据的可靠读取和处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值