Ожидание ключевого слова от сервера Qt C++

Всем доброго времени суток! Есть такой код

Main.cpp

    int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    Clien c;
    return a.exec();
}

Client.cpp

QTcpSocket *client = new QTcpSocket();
client->connectToHost("192.168.1.133", 5555);
if( Q_UNLIKELY(!client->waitForConnected())) {
    qFatal("Не дозвонился");
}

AUTH cl;
QByteArray key;
cl.auth(&client, key);

Auth.cpp

bool AUTH::auth(QTcpSocket **client_1, QByteArray &key)
{
    client = *client_1;
    QObject::connect(client, &QTcpSocket::readyRead, [this]{
        QString msg { client->readAll() };
        qInfo() << "Сервер:" << msg;
        if(msg == "Да, алё") {
            client->write(get_mess().toUtf8());
        }
        else if(msg == "Какими деньгами") {
            client->write("Ну которые я внес в капитал");
        }
        else if(msg == "Куда?") {
            client->write("В капитал прожиточного минимума");
        }
        else if(msg == "Ты пьяный или кто, сынок") {
            client->write("Я Михал Палыч Терентьев");
        }
        else if(msg == "Кто такой") {
            client->write("Пьяный");
            client->close();
        }
        client->waitForBytesWritten();
        return false;
    });
    client->write("Привет");
}

Между клиентом и сервером происходит 'общение' (аутентификация, в будущем). И мне необходимо, чтоб сначала это "общение" закончилось и продолжилось выполнение программы. Если я сделаю так:

Client.cpp

    QTcpSocket *client = new QTcpSocket();
    client->connectToHost("192.168.1.133", 5555);
    if( Q_UNLIKELY(!client->waitForConnected())) {
        qFatal("Не дозвонился");
    }

    AUTH cl;
    QByteArray key;
    cl.auth(&client, key);
    client->write("cool"); // добавлю, чтоб после аутентификации отправилось сообщение

То первое отправленное сообщение серверу будет слипленно с "cool". Т.е при подключении должно отправляться сообщение "Привет", а отправляется "Приветcool".

Вопрос: как реализовать так, чтоб сначала произошла аутентификация, т.е (полностью прошла функция auth), а потом уже серверу отправилось сообщение "сool". Надеюсь понятно объяснил)

Заранее Всем спасибо!!:)


Ответы (2 шт):

Автор решения: nevilad

Код аутентификации можно выполнить в цикле, который выходит только тогда, когда аутентификация провалена либо прошла. Код не проверяет, что все стадии аутентификации из if\else прошли и прошли в определенном порядке. Хотя в вопросе об этом не сказано, полагаю задумывалось именно так. Для обработки порядка добавил изменения и проверки stage.

bool AUTH::auth(QTcpSocket **client_1, QByteArray &key)
{
    client = *client_1;
    QObject::connect(client, &QTcpSocket::readyRead, [this]{
      int stage = 0;
      do {
        QString msg { client->readAll() };
        qInfo() << "Сервер:" << msg;
        if(!stage && msg == "Да, алё") {
            client->write(get_mess().toUtf8());
            stage = 1;
        }
        else if(stage == 1 && msg == "Какими деньгами") {
            client->write("Ну которые я внес в капитал");
            stage = 2;
        }
        else if(stage == 2 && msg == "Куда?") {
            client->write("В капитал прожиточного минимума");
            stage = 3;
        }
        else if(stage == 3 && msg == "Ты пьяный или кто, сынок") {
            client->write("Я Михал Палыч Терентьев");
            stage = 4;
        }
        else if(stage == 4 && msg == "Кто такой") {
            client->write("Пьяный");
            //client->close(); Зачем закрывать, если дальше в него пишут?
            client->waitForBytesWritten();
            return true; //auth прошла
        }
        else
          return false; //auth не прошла
        client->waitForBytesWritten();
      }
      while(1);
    });
    client->write("Привет");
    client->waitForBytesWritten();
}
→ Ссылка
Автор решения: Alexander Chernin

Попробуйте через сигнал сообщить всем подписантам, что аутентификация закончена. Что-то типа этого:

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);    
    Client client;
    if (!client.connectToHost() ) { // Внутри QTcpSocket и waitForConnected
        // не соединились
    } else {
        // Соединились - пробуем аутентифицироваться
        Auth auth;
        // Сигнал - результат авторизации/аутентификации
        QObject::connect(&auth, &Auth::authResult, [&](boolean value) {
            // Аутентификация завершилась успешно/неуспешно
            if (/*Успешно, то*/) {
                client.send("Cool");
            }
        });
        // Начинаем аутентификацию
        auth.auth(client);
        return a.exec();
    }    
    return 0;
}

Естественно, классы Auth и Client должны быть наследниками QObject

→ Ссылка