结合使用阻塞功能和信号(QTcpSocket)

时间:2018-11-16 08:56:50

标签: c++ qt

我写了一个AsyncSocket,它使用QTcpSocket与某些服务器一起工作。它们(服务器)是很久以前写的,我无法更改它们。

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

我以为使用了QAbstractSocket::waitForReadyRead(int msecs),但在Qt documentation(“详细信息”部分的末尾)找到了

  

注意:我们不建议将阻止功能与   信号。应该使用两种可能性之一。

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

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();
};

更新:使用readyRead

捕获丢失的AsyncSocket信号来组织消息队列可能很有用。

1 个答案:

答案 0 :(得分:0)

我按照 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.
}