Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: QTcpSocket и синхронный протокол
Форум на CrossPlatform.RU > Библиотеки > Qt > Qt Ввод/Вывод, Сеть. Межпроцессное взаимодействие
canavar
Все доброго вечера.

Непонятно, как решать вот такую проблему. Существует синхронный протокол передачи уровня приложения. Я посылаю команду, жду - приходит ответ. В простом режиме работы с QTcpSocket все понятно: создали, соединили сигналы со слотами. Отправляем данные, когда нам отвечают - вызывается слот OnReadyRead() и дальше делаем с данными все что хотим.

Есть желание сделать метод, который будет возвращать весь ответ, то типа того:

QStringList getAnswer(QString &cmd);

То есть я вызываю этот метод с необходимой командой в параметре, а на выходе получаю список строк, который пришел от сервера.

Такое вообще реально реализовать?

Заранее спасибо.
kwisp
canavar,
можно. элементарное из ассистента что на ум пришло это qWait(int msec) можно использовать.
Litkevich Yuriy
Цитата(canavar @ 27.3.2009, 1:54) *
То есть я вызываю этот метод с необходимой командой в параметре, а на выходе получаю список строк, который пришел от сервера.
я с сеткой не работал, но механизм в синхронных комуникациях примерно один и тот же:
создаешь доппоток и реализуешь в нем свой протокол. Делаешь слот типа sendCommand и сигнал ready.
Вместо getAnswer используешь sendCommand, ну а по сигналу ready читаешь уже все данные.
igor_bogomolov
По поводу qWait(int msec) ничего сказать не могу, никогда ее не использовал. Хотя в ассистенте написано, что Gui и сетевой интерфейс она не блокирует. Правильно ли это тянуть с собой в приложении функционал из QTestLib?

Мне не совсем понятно, что значит "весь ответ". У Вас есть критерий, по которомы Вы можете определить, что все ожидаемые данные получены? Или единственным критерием будет являться то, что в соккет какое-то время данные не поступают.

В любом случае, я вижу только два пути. Первое - организовать все через блокирующую функцию waitForReadyRead(int msecs), т.е. примерно так
Раскрывающийся текст
const QStringList & getAnswer(const QString &cmd) {
    socket.write(qPrintable(cmd));
    socket.flush();

    QStringList strlist;
    forever {
        if(waitForReadyRead(1000)) {
            strlist << socket.read(socket.bytesAvailable());
        } else break;
    }
    return strlist;
}

Что, как сами понимаете, делать не стОит, т.к. Gui будет заблокированно на неопределенное время. (Хотя всегда можно добавить qApp->processEvents(). Но мне такой подход не нравится.)

Во втором случае - это, как уже предлогалось, сделать все это в дочернем потоке. Правда структура проекта будет несколько иной, что Вы изначально хотели.

Раскрывающийся текст
void ThreadSocket::run()
{
    QStringList strlist;
    emit SendServer("cmd"); // отправляем данные для записи в соккет
    QMutexLocker locker(&mutex);
    forever {
        if ( cond.wait(&mutex, 1000) ) {
            strlist << DataIn; //  DataIn - данные полученные по соккету, в обработчике события readyRead()
            DataIn.clear();
        } else break;
    }
    emit sendData(strlist); // отправляем полученные данные.
}

P.S. Коды не компилил. Надеюсь сильно нигде не облажался :rolleyes:
canavar
"Весь ответ" -- имеется ввиду следущее: читаем данные, пока не будет строки, вида: "xxx end", где xxx - код ответа.

Спасибо огромное! Я сделал через отдельный поток, то есть я пошел по второму пути. :)

Еще раз спасибо.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Форум IP.Board © 2001-2020 IPS, Inc.