我编写了一个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.
}