将阻塞功能与信号一起使用(QTcpSocket)



我编写了一个AsyncSocket,它使用QTcpSocket来处理一些服务器。它们(服务器(是很久以前写的,我没有能力更改它们。

因此,问题是如果服务器无法识别消息(因为它对default消息类型没有任何操作(,则会缺少readyRead信号。我认为这是服务器的问题,因为它无论如何都应该响应。。。但这不是我自己的代码,我必须像现在这样使用它。

我想使用QAbstractSocket::waitForReadyRead(int msecs),但在Qt文档中找到了("详细信息"部分的末尾(:

注意:我们不鼓励将阻塞函数与信号。应该使用两种可能性中的一种。

所以,我有点困惑为什么我不应该使用这样的阻塞方法:

void AsyncSocket::send(const QByteArray &msg)
{
socket->write(msg);
if (!socket->waitForReadyRead(msecs))
qDebug() << "Warning! ReadyRead were not emitted";
}

服务器的工作方式如下:

switch(received_msg.type)
{
case TYPE_ONE: // do smth
break;
case TYPE_TWO: // do smth
break;
case TYPE_N:   // do smth
break;
default: 
// do NOTHING
}

我的班级:

class AsyncSocket
{
public:
void connectToHost(const QString &host, qint16 port);
void send(const QByteArray &msg);
void disconnectFromHost();
// other public members
public slots:
void connected();
void readyRead();
};

UPDATE:捕获丢失的readyRead信号以使用AsyncSocket组织消息队列可能很有用

我按照Felix关于QTimer的建议解决了这个问题,如下所示:

class AsyncSocket
{
public:
void connectToHost(const QString &host, qint16 port);
void send(const QByteArray &msg);
void disconnectFromHost();
// other public members
signals:
void dataReady(const QByteArray &data);
public slots:
void connected();
void readyRead();
private slots:
// I created the timer timeout signal here connected in AsyncSocket constructor
void missRead(); 
private:
QTimer *timer; // and timer pointer here allocated in constructor also
};

当用户发送消息时,我启动计时器:

bool AsyncSocket::send(const QByteArray &msg, int responseSize)
{
// successfull sending code here
timer->start(msecs);
return true;
}

我用信号来处理这样的阅读情况:

void AsyncSocket::readyRead() // successfull reading
{
if (socket->bytesAvailable() == responseSize) // buffer has all data
{
timer->stop();
emit (dataReady(socket->readAll()));
// reset device, clear buffer, etc.
}
}
void AsyncSocket::missRead() // server stoped to reply
{
timer->stop();
emit(dataReady(QByteArray()));
// reset device, clear buffer, etc.
}

最新更新