LINUX.ORG.RU

Как правильно организовать логику + потоки qt

 , , ,


0

2

Запутался в конец. Вообщем ситуация следующая:

Есть некое устройство, доступ к которому я получаю через виртуальный com-порт с помощью QSerialPort, далее - девайс.

Девайс принимает n-ое кол-во комманд, при этом время ответа на команду разное, эти команды, так сказать являются «транспортным» уровнем для проброса протокола, в итоге я не знаю как отследить на какую команду пришел ответ.

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

Поток создаю наследуz класс от QThread и переопределением метода run(), но нет понимания что должно быть внутри этого метода.

Последнее, что крутится в голе, это: Вынести класс для работы с девайсом(QSerialPort) в отдельный поток и реализовать в нем 2 типа комманд(транспортный уровень).

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

Ответ на: комментарий от CrossFire

Команды зашифрованы, и их содержимое динамическое.

Например у меня есть команда getParam1();

Эта команда шифруется в спец. формат и отправляется устройству, затем приходит ответ ParamX = «И где то тут есть Param1»; судить о том что он там есть я могу только по команде которую отправил, т.е. если отправил getParam1() должен прийти ответ на эту команду и все.

jeka_sharapov
() автор топика

можно не заморачиваться сразу с потоком, попробуй неблокирующий ввод-вывод на сигналах (readyRead в частности)
только смотри не наступи на граблю: http://www.prog.org.ru/topic_24594_0.html

dib2 ★★★★★
()

Я, честно говоря, не сталкивался с железяками, но вижу только два варианта: или ждать ответ или нумеровать (если, конечно, железяка сколько-нибудь умная), как сделано даже в TCP, иначе узнать что к чему, наверное, не получится.

sudo cast Eddy_Em

CrossFire ★★★★★
()

в итоге я не знаю как отследить на какую команду пришел ответ.

В начале ответа делай эхо этой команды. Делов-то!

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

Не все так просто)

Еще такой наболевший вопрос, почему могут биться данные на куски при readyRead() ?

void SslClient::socketReadyRead()
{
    static QByteArray data;
    data += socket->readAll();
    if(data.mid(data.size() - 8) == "finished") { //если в конце стоит finished -
                                                 //пакет можно отправить на обработку
      emit(readSSL(data.replace(QByteArray("finished"), QByteArray(""))));
      data = "";
    }
}

Приходится вот так извращаться

jeka_sharapov
() автор топика
Ответ на: комментарий от Eddy_Em

Я-то тут при чем? Где я и где культи? Ой вей...

Я просто не знаю кто тут еще с железяками возится, суть не в кутэ, а в том как организовать взаимодействие грамотно.

CrossFire ★★★★★
()

Примерный вывод комманд

Соединение установленно. Запросили смс «OK» «+CMGL: 0,1,,156 07919730071111F1040B919706842844F70000415050214054619C30980C948B8162B919080683C16020180C0682C16020180C0682C16020180C0682C16020180C0682C16020180C0483816030100C0682C1403018080603C16020180C0483816030100C0682C1403018080603C16020180C0483816030100C0682C1403018080603C16020180C0483816030100C0682C1403018080603C16020180C0483816030100C06 +CMGL: 1,1,,156 07919730071111F1040B919706842844F70000415050216002619C30980C948B8162B919080683C16020180C0682C16020180C0682C16020180C0682C16020180C0682C16020180C04» «83816030100C0682C1403018080603C16020180C0483816030100C0682C1403018080603C16020180C0483816030100C0682C1403018080603C16020180C0483816030100C0682C1403018080603C16020180C0483816030100C06 +CMGL: 2,1,,156 07919730071111F1040B919706842844F70000415050214214619C30980C048B8162B919080683C16020180C0682C16020182C0682C16020180C0682C16020180C0682C162A0980C149381603710EC0682DD403018080603C16020180C0483816030100C0682C1403018080603C16020180C0483816030100C0682C1403018080603C16020180C0483816030100C0682C1403018080603C16020180» «C0483816030100C06 +CMGL: 3,1,,156 07919730071111F1040B919706842844F70000415050415533619C30980C948B8162B919080683C1602018CC0682C16020184C0682C16020180C0682C16020180C0682C16220D80D149381603510EC0682DD403018080603C16020180C0483816030100C0682C1403018080603C16020180C0483816030100C0682C1403018080603C16020180C0483816030100C0682C1403018080603C16020180C0483816030100C06 +CMGL: 4,1,,156 07919730071111F1040B919706842844F70000415050419574619C30980C948B8162B919080683C1602018CC0682C16020184C0682C16020180C0682C16020180» «C0682C16220D80D149381603510EC0682DD403018080603C16020180C0483816030100C0682C1403018080603C16020180C0483816030100C0682C1403018080603C16020180C0483816030100C0682C1403018080603C16020180C0483816030100C06 +CMGL: 5,1,,156 07919730071111F1040B919706842844F70000415050817404619C30980C948B8162B919080683C1602018CC0682C16020184C0682C16020180C0682C16020180C0682C16220D80D149381603510EC0682DD403018080603C16020180C0483816030100C0682C1403018080603C16020180C0483816030100C0682C1403018080603C16020180C0483816030100C0682C14030» «18080603C16020180C0483816030100C06

OK» ^C jeka@N56VJ:~$ /home/jeka/build-readscancode-Desktop_Qt_5_2_0_GCC_32bit-Debug/readscancode Соединение установленно. Запросили баланс «OK» «84.47» «+CUSD: 0,„C2303BEC9E83703417ED0692BB1455BD3BACA69741D6F01C5D07CDEBE493B80E728741E1395DFE86BFE5F430BB1C02D5E42F320B740391DD2E71790E67BB402A5ACD3602“,15» Запросили баланс «OK» «84.47» «+CUSD: 0,„C2303BEC9E83703417ED0692BB1455BD3BACA69741D6F01C5D07CDEBE493B80E728741E1395DFE86BFE5F430BB1C02D5E42F320B740391DD2E71790E67BB402A5ACD3602“,15» ^C jeka@N56VJ:~$

jeka_sharapov
() автор топика

Если в ответе от дивайса есть тип команды - то как вариант, ставить команды одного типа в очередь, и не толкать следующую пока не придет ответ на предыдущую.

Но вообще, если протокол весь такой непоследовательный и ассинхронный, то в нем должен быть способ сопоставить команду и ответ, иначе грошь цена ему.

Имхо автор чего то не понимает, либо дивайс не даст в себя писать, пока не ответит, либо в ответе содержится некий ID запроса.

batbko
()
Ответ на: комментарий от CrossFire

Я вожусь с железками, но я не настолько ССЗБ, чтобы культи использовать!

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от jeka_sharapov

Это ужас.

Ты лучше бы:
а) описал точно проблему, нафига тебе так уродоваться?
б) не извращался бы с культями и недоООПщиной!

Eddy_Em ☆☆☆☆☆
()

Самое простое - блокирующий ввод/вывод. Отправил команду и ждешь ответа на нее, и только потом отправляешь следующие команды.

Moncruist
()
Ответ на: комментарий от jeka_sharapov

потому что readyRead срабатывает по своим внутренним соображениям (интерчар таймаут или заполнение буфера), а не тогда, когда у тебя _логическое_ завершение пакета. Более того, QUdpSocket например, еще и датаграммы клеит (очень редко, но бывает). Поэтому чтение из устройства всегда воспринимай как поток с неожиданностями, и лепи разбивку на уровне логики (собственно твой пример)

dib2 ★★★★★
()

Поток создаю наследуz класс от QThread и переопределением метода run(), но нет понимания что должно быть внутри этого метода.

Вообще, рекомендуют не наследовать QThread, а наследовать свой класс от QObject и после создания объекта перемещать его в нужный поток moveToThread.

QThread *thread = new QThread( this );
thread->start();

MySerialListener *object = new MySerialListener;
// тут связываем всякие сигналы-слоты
object->moveToThread( thread );

Как-то так можно.

grondek
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.