繁体   English   中英

等待客户端上服务器的响应

[英]Wait for response from server on client

我正在尝试验证用户的登录名,因此我向服务器发送了用户名和密码,服务器根据数据库检查了该数据,如果验证成功或失败,则会发送是/否。 客户端收到此消息,并发出readyRead()信号,我使用一个插槽来处理它。

我有这个登录功能:

bool Client::login(QString username, QString password){

    //some code

    client.write(clientSendBuf); //send the data to the server
    //wait for response
    //if response is good, return true
    //else return false
}

我想等待服务器的响应,然后用login返回true或false。 我知道如何很好地接受来自服务器的响应,但是我基本上希望发送数据,并且客户端程序将停止,直到我们获得响应或一段时间后才超时。

如何在Qt中做到这一点?

http://qt-project.org/doc/qt-4.8/qiodevice.html#waitForReadyRead

QTcpSocket client;

if(client.waitForReadyRead(15000)){
    //do something if signal is emitted
}
else{
    //timeout
}

我没有正确查看文档。 我找到了答案。

你真的不想写这样的代码。 请记住,所有的waitFor...exec方法都可以重新输入您的代码,因此是难以发现错误的来源。 不,他们在最不适当的时刻重新进入。 也许当您向客户进行演示时,或者当您将第一个系统交付给Elbonia时:)

login成功后,客户端应发出信号。 有一个登录请求,以及对此请求的响应。 您可以使用QStateMachine通过此类响应来指导整个应用程序的逻辑。

下面的示例假定网络协议随时都支持一个以上的请求。 摆脱处理程序队列并只允许一个处理程序很简单。

class Client : public QObject {
  Q_OBJECT
  typedef bool (Client::*Handler)(); // returns true when the request is finished
  QTcpSocket m_client;
  QByteArray m_buffer;
  QQueue<Handler> m_responses; // always has the idle response on the bottom
  ...
  Q_SLOT void hasData() {
    Q_ASSERT(! m_responses.isEmpty());
    m_buffer += m_client.readAll();
    while (! m_buffer.isEmpty()) {
      if (m_reponses.head()()) m_responses.dequeue();
    }
  }
  bool processIdleRsp() {
    // Signal an error condition, we got data but expect none!
    return false; // Must never return true, since this response mustn't be dequeued.
  }
  bool processLoginRsp() {
    const int loginRspSize = ...;
    if (m_buffer.size() < loginRspSize) return false;
    bool success = false;
    ... // process the response
    emit loginRsp(success);
    m_buffer = m_buffer.mid(loginRspSize); // remove our response from the buffer
    return true;
  }
public:
  Client(QObject * parent = 0) : QObject(parent), m_state(Idle) {
    connect(&m_client, SIGNAL(readyRead()), SLOT(hasData());
    m_responses.enqueue(&Client::processIdleRsp);
  }
  Q_SLOT void loginReq(const QString & username, const QString & password) {
    QByteArray request;
    QDataStream req(&request, QIODevice::WriteOnly);
    ...
    m_client.write(request);
    m_responses.enqueue(&Client::processLoginRsp);
  }
  Q_SIGNAL void loginRsp(bool success);
};

如果要传输大量数据,则可以对缓冲区使用循环队列以加快处理速度。 照原样,在处理完每个响应之后,会将剩余数据推到缓冲区的前面。

问题未解决?试试以下方法:

等待客户端上服务器的响应

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2023 STACKOOM.COM