crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в данную темуНачать новую тему
> QTcpSocket и синхронный протокол, Как получать ответ
canavar
  опции профиля:
сообщение 26.3.2009, 22:54
Сообщение #1


Студент
*

Группа: Новичок
Сообщений: 14
Регистрация: 26.3.2009
Пользователь №: 643

Спасибо сказали: 0 раз(а)




Репутация:   0  


Все доброго вечера.

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

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

QStringList getAnswer(QString &cmd);

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

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

Заранее спасибо.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
kwisp
  опции профиля:
сообщение 26.3.2009, 23:16
Сообщение #2


астарожна ынтжинэр
*****

Группа: Участник
Сообщений: 1404
Регистрация: 26.11.2008
Из: ТаганрогРодинаЧехова
Пользователь №: 435

Спасибо сказали: 113 раз(а)




Репутация:   23  


canavar,
можно. элементарное из ассистента что на ум пришло это qWait(int msec) можно использовать.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 27.3.2009, 1:43
Сообщение #3


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9656
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(canavar @ 27.3.2009, 1:54) *
То есть я вызываю этот метод с необходимой командой в параметре, а на выходе получаю список строк, который пришел от сервера.
я с сеткой не работал, но механизм в синхронных комуникациях примерно один и тот же:
создаешь доппоток и реализуешь в нем свой протокол. Делаешь слот типа sendCommand и сигнал ready.
Вместо getAnswer используешь sendCommand, ну а по сигналу ready читаешь уже все данные.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
igor_bogomolov
  опции профиля:
сообщение 27.3.2009, 3:20
Сообщение #4


Профессионал
*****

Группа: Сомодератор
Сообщений: 1215
Регистрация: 22.3.2009
Из: Саратов
Пользователь №: 630

Спасибо сказали: 235 раз(а)




Репутация:   29  


По поводу 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
  опции профиля:
сообщение 28.3.2009, 0:12
Сообщение #5


Студент
*

Группа: Новичок
Сообщений: 14
Регистрация: 26.3.2009
Пользователь №: 643

Спасибо сказали: 0 раз(а)




Репутация:   0  


"Весь ответ" -- имеется ввиду следущее: читаем данные, пока не будет строки, вида: "xxx end", где xxx - код ответа.

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

Еще раз спасибо.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 10.7.2020, 0:33