Название: QTCPSocket в отдельном потоке. Отправлено: GPPsoft от Декабрь 22, 2013, 08:51 Здравствуйте. Как правильно заставить QTCPSocket принимать и обрабатывать данные в отдельном потоке? Сейчас у меня сделано так:
Код: connect(tcpSocket,SIGNAL(connected()),this,SLOT(on_connected())); Три сигнала... первые два меня устраивают в плане того что ни выполняются в потоке UI, но вот получение и обработка данных необходима в отдельном потоке. Как реализовать? Как я понимаю сейчас данные обрабатываются в UI потоке. Код: void MainWindow::on_data() Спасибо! Название: Re: QTCPSocket в отдельном потоке. Отправлено: Bepec от Декабрь 22, 2013, 11:53 Читаем про QThread.
Есть два способа. 1) создать класс с нужным вам функционалом, создать новый поток(QThread) и перенести его (moveToThread) в отдельный поток. 2) создать наследника от QThread и в нём в конструкторе сделать moveToThread(this). И в этом наследнике творите что хотите. Оба способа равнозначны, единственно что в первом можно будет разделять поток и класс(отдельные сущности),а во втором они будут единым целом. PS мне больше нравится второй из-за экономии сущностей. Задач по перебросам из потока в поток, для которых необходим первый способ мне ещё не встречалось. Название: Re: QTCPSocket в отдельном потоке. Отправлено: Nidxogg от Январь 14, 2014, 21:46 Читаем про QThread. Несколько вопросов:Есть два способа. 1) создать класс с нужным вам функционалом, создать новый поток(QThread) и перенести его (moveToThread) в отдельный поток. 2) создать наследника от QThread и в нём в конструкторе сделать moveToThread(this). И в этом наследнике творите что хотите. Оба способа равнозначны, единственно что в первом можно будет разделять поток и класс(отдельные сущности),а во втором они будут единым целом. PS мне больше нравится второй из-за экономии сущностей. Задач по перебросам из потока в поток, для которых необходим первый способ мне ещё не встречалось. 1)А можете показать, где в документации на QThread это написано? (про moveToThread) 2)По второму способу. Если без moveToThread вывести в контруктуре gui-класса и конструкторе наследника QThread Код: qDebug()<<this->thread() Если смотреть через Цитировать qDebug()<<QThread::currentThread(); , то разныеВообщем запутался ??? Название: Re: QTCPSocket в отдельном потоке. Отправлено: Bepec от Январь 14, 2014, 22:14 QThread - myThread;
До запуска потока Код: myThread.start() После Код: myThread.start() moveToThread(this) в конструкторе переносит весь myThread в него самого :D Это интересный момент. И после Код: myThread.start() В каком же потоке вызываться будет слот, зависит от типа соединения. Это тоже отдельная песня :) PS Я сам доходил до этого неделю, если не больше. Интернета не было, потому исписывал бумажку :D Название: Re: QTCPSocket в отдельном потоке. Отправлено: Nidxogg от Январь 14, 2014, 22:18 Цитировать инициализируется поток, и метод run() начинает выполнятся в новом потоке. зачем тогда moveToThread(this), если добились "желаемого?"Название: Re: QTCPSocket в отдельном потоке. Отправлено: Old от Январь 14, 2014, 22:25 зачем тогда moveToThread(this), если добились "желаемого?" Тут цель не в этом.Стоит сразу отметить, что все потоки выполняются в одном адресном пространстве и реально никаких контекстов нет. Их искусственно вводи Qt, что бы у него была возможность решать какой тип соединения connect использовать в том или ином случае, при испускании сигнала. Т.е. если два объекта порожденных от QObject, находятся в одном контексте, то будет использоваться DirectConnect (прямой вызов метода), если в разных - QueueConnect (вызов через очередь событий нити получателя). Название: Re: QTCPSocket в отдельном потоке. Отправлено: Bepec от Январь 14, 2014, 22:26 Если не сделать moveToThread, то все прочие методы наследника от QThread будут выполняться в потоке родителя.
run - всегда в новом. Прочие - после moveToThread. Название: Re: QTCPSocket в отдельном потоке. Отправлено: Old от Январь 14, 2014, 22:30 Да, и про moveToThread забыл написать... :)
При конструировании Q-объекта он начинает принадлежать контексту той нити в которой создан, а moveToThread перемещает этот объект в контекст указанной нити. Название: Re: QTCPSocket в отдельном потоке. Отправлено: Nidxogg от Январь 15, 2014, 06:18 Спасибо
Название: Re: QTCPSocket в отдельном потоке. Отправлено: stix357 от Декабрь 20, 2016, 08:05 QThread - myThread; Мммм, попробую поднять тему.До запуска потока Код: myThread.start() После Код: myThread.start() moveToThread(this) в конструкторе переносит весь myThread в него самого :D Это интересный момент. И после Код: myThread.start() В каком же потоке вызываться будет слот, зависит от типа соединения. Это тоже отдельная песня :) PS Я сам доходил до этого неделю, если не больше. Интернета не было, потому исписывал бумажку :D Предложенные варианты: Цитировать Есть два способа. Вариант 1- работает, но странно:1) создать класс с нужным вам функционалом, создать новый поток(QThread) и перенести его (moveToThread) в отдельный поток. 2) создать наследника от QThread и в нём в конструкторе сделать moveToThread(this). И в этом наследнике творите что хотите. Оба способа равнозначны, единственно что в первом можно будет разделять поток и класс(отдельные сущности),а во втором они будут единым целом. PS мне больше нравится второй из-за экономии сущностей. Задач по перебросам из потока в поток, для которых необходим первый способ мне ещё не встречалось. Код: TCPClientQt::TCPClientQt(): QTcpSocket() отрабатываются сигналы Код: connect(m_pTcpSocket, SIGNAL(connected()), SLOT(slotConnected())); не отрабатывают Код: connect(m_pTcpSocket, SIGNAL(error(QAbstractSocket::SocketError)),this, SLOT(slotError(QAbstractSocket::SocketError))); Вариант 2 - не работает на Win7-32, Qt-4.8.1 Сокет запускается в основном потоке. Гуй виснет. При получении сокетом пакета. Вариант 3 - создание наследника QTcpSocket в наследнике QThread в методе run() согласно рекомендациям Шлее Код: ReadData::ReadData(QObject *parent) : В чем мой косяк? Название: Re: QTCPSocket в отдельном потоке. Отправлено: Bepec от Декабрь 20, 2016, 11:55 1) вы создали TCPSocket и указали ему родителя. И будет он жить теперь в потоке родителя (this). Перенос в поток вы не осуществили.
1*) отработка сигналов должна работать в любом случае, видимо вы где то ошиблись, что без полного кода проекта сказать невозможно. 2) Хз что вы там наделали, но явно всё неправильно. Приводите код, а не "я сделал, оно не работает, способ плохо, код не покажу, я идеален" :D 3) Опять таки нет полного кода :D Ничего сказать не могу. Название: Re: QTCPSocket в отдельном потоке. Отправлено: stix357 от Декабрь 20, 2016, 12:14 1) вы создали TCPSocket и указали ему родителя. И будет он жить теперь в потоке родителя (this). Перенос в поток вы не осуществили. 1 - нет, не так1*) отработка сигналов должна работать в любом случае, видимо вы где то ошиблись, что без полного кода проекта сказать невозможно. 2) Хз что вы там наделали, но явно всё неправильно. Приводите код, а не "я сделал, оно не работает, способ плохо, код не покажу, я идеален" :D 3) Опять таки нет полного кода :D Ничего сказать не могу. Это в приложении Код В конструкторе наследника сокета : Код 2) Хм, классы вывалить? Портянка получится, но попробую %) Код
Код
//Цикл нужен потому, что с сервера не все данные могут прийти одновременно. //Поэтому клиент должен быть в состоянии получать как весь блок целиком, //так и только часть блока или даже все блоки сразу. //размер блока заранее не известен может и 2 к быть, а может и 20 к. //промышленный контроллер после получения команды старт гонит цепочку байт (8 бит на датчик) //предваряя посылку признаком начала, а при корректном завершении признак завершения передачи Код
Код
Блин, все комменты на русском злобно перегнало в другую кодировку Как побороть не знаю. :( А если в конструкторе потока создать сокет, и попытаться поток сам в себя перенести, он продолжает жить в основном потоке Код
Название: Re: QTCPSocket в отдельном потоке. Отправлено: stix357 от Декабрь 21, 2016, 11:18 Далее:
то что не отрабатывает Код наврал отрабатывает при попытке получения пакета в Код только по Network operation timed out На остальные ошибки ... типо плевать Хоть IP задавай несуществующий, хоть порт левый .... тупо отправляется SYNC и полный завис (смотрю в Tcpview) ClientADC_QT.exe 1844 TCP pc-win7060.dlink 50120 192.168.1.200 32000 SYN_SENT и в Wireshark чисто, чисто, чисто А при запуске из основного потока с ГУИ все робит ...... парадокс Название: Re: QTCPSocket в отдельном потоке. Отправлено: stix357 от Декабрь 29, 2016, 09:05 Цитата: Bepec 2) создать наследника от QThread и в нём в конструкторе сделать moveToThread(this). И в этом наследнике творите что хотите. Вообще довольно спорный способ переносить объект QThread в самого себя в конструкторе.До отработки конструктора объект еще не существует. Название: Re: QTCPSocket в отдельном потоке. Отправлено: Bepec от Декабрь 29, 2016, 13:18 Неверно.
Сначала создаётся объект. Потом вызывается конструктор. Всё есть. Название: Re: QTCPSocket в отдельном потоке. Отправлено: stix357 от Декабрь 30, 2016, 11:55 Неверно. Только заготовка. Благодаря опять-таки конструктору предка.Сначала создаётся объект. Потом вызывается конструктор. Всё есть. 2) создать наследника от QThread и в нём в конструкторе сделать moveToThread(this). И в этом наследнике творите что хотите. Не сочтите за наглость, но возможно вас не затруднит показать простенький работающий пример по вашему методу? QTcpSocket в отдельном QThread Если я правильно понял, то должно выглядеть примерно так: Код
Название: Re: QTCPSocket в отдельном потоке. Отправлено: Bepec от Декабрь 30, 2016, 15:48 Вы не понимаете...
Вы сначала создаёте объект... потом перемещаете все слоты потока в самого себя :D Объект при этом у вас никуда не перемещается. Примерчик. Самый примитив. https://dl.dropboxusercontent.com/u/62712483/Temp.zip Название: Re: QTCPSocket в отдельном потоке. Отправлено: stix357 от Январь 09, 2017, 14:47 Вы не понимаете... Благодарю, буду сравнивать и смотреть где напортачил. Руки пока не доходили.Вы сначала создаёте объект... потом перемещаете все слоты потока в самого себя :D Объект при этом у вас никуда не перемещается. Примерчик. Самый примитив. https://dl.dropboxusercontent.com/u/62712483/Temp.zip Название: Re: QTCPSocket в отдельном потоке. Отправлено: stix357 от Январь 11, 2017, 07:23 Примерчик. Самый примитив. Вопрос возник:https://dl.dropboxusercontent.com/u/62712483/Temp.zip если по вашему примеру Код то что произойдет с распределением памяти при завершении void SBThread::run()? выделенная память под m_pTcpSocket сама освободится или это надо делать ручками? Название: Re: QTCPSocket в отдельном потоке. Отправлено: Пантер от Январь 11, 2017, 08:58 Объект сокета будет жить, пока жив класс потока. Создавай на стеке.
Название: Re: QTCPSocket в отдельном потоке. Отправлено: stix357 от Январь 11, 2017, 09:21 Объект сокета будет жить, пока жив класс потока. Создавай на стеке. Mмм, не понял фразу Создавай на стеке. А если так? Код
Название: Re: QTCPSocket в отдельном потоке. Отправлено: Пантер от Январь 11, 2017, 09:24 Так объект сокета разрушится при выходе из метода run. Это и есть на стеке.
Название: Re: QTCPSocket в отдельном потоке. Отправлено: Пантер от Январь 11, 2017, 09:25 Еще советую не наследоваться от QThread, а делать moveToThread. На форуме есть обсуждение данного совета со ссылками.
Название: Re: QTCPSocket в отдельном потоке. Отправлено: gil9red от Январь 11, 2017, 09:35 Еще советую не наследоваться от QThread, а делать moveToThread. На форуме есть обсуждение данного совета со ссылками. В доке написано что можно и так, и так :) http://doc.qt.io/qt-5/qthread.html#details // You can use worker objects by moving them to the thread using QObject::moveToThread(). Код
// Another way to make code run in a separate thread, is to subclass QThread and reimplement run(). For example: Код
Название: Re: QTCPSocket в отдельном потоке. Отправлено: Пантер от Январь 11, 2017, 09:48 gil9red, ну, ясен пень, что не расстреляют за любой из способов. Просто я считаю, что наследование худший выбор. Вообще, ИМХО, лучше сначала все писать без потоков (на ассинхронке), а потом выносить в потоки нужные части, при этом moveToThread будет лучшим решением, чем изменение наследования.
Название: Re: QTCPSocket в отдельном потоке. Отправлено: stix357 от Январь 11, 2017, 10:08 Объект сокета будет жить, пока жив класс потока. Создавай на стеке. Вот я и думаю, как на утечки памяти не напороться ...Ведь в случае Код если я объекту SBThread потока дам команду quit(), то m_pTcpSocket в памяти останется но если потом скажу объекту SBThread - start(), то получается дубликат m_pTcpSocket будет создан .... а старый повиснет непонятно где. Ладно, спасибо, буду экспереминтировать. Название: Re: QTCPSocket в отдельном потоке. Отправлено: Пантер от Январь 11, 2017, 10:14 Да, будет утечка. Либо в run проверку делай
Код Либо создавай на стеке. Название: Re: QTCPSocket в отдельном потоке. Отправлено: stix357 от Январь 11, 2017, 10:51 Да, будет утечка. Либо в run проверку делай А при moveToThread что произойдет с объектом при завершении run() в двух вариантах?Код Либо создавай на стеке. 1) Код 2) Код Я просто не в курсе, как в QT утечки отследить, всего месяц с ним работаю. Название: Re: QTCPSocket в отдельном потоке. Отправлено: Авварон от Январь 11, 2017, 11:00 +1 за moveToThread. Переопределение run() нужно если дергается одна ф-ия и нет сигнал-слотового взаимодействия.
И указывать this у перемещаемого класса нельзя, перемещать можно только объекты без родителя (точнее, только топ-левел объект иерархии). Название: Re: QTCPSocket в отдельном потоке. Отправлено: Пантер от Январь 11, 2017, 11:13 stix357, просто QTcpSocket смысла нет переносить в поток. Да и вообще, тебе тут поток не нужен, если работаешь с сокетом сигналами/слотами. Вот тебе пример с moveToThread.
Код
Что непонятно, спрашивай. Писал в браузере - возможны ошибки. Название: Re: QTCPSocket в отдельном потоке. Отправлено: stix357 от Январь 11, 2017, 11:48 stix357, просто QTcpSocket смысла нет переносить в поток. Да и вообще, тебе тут поток не нужен, если работаешь с сокетом сигналами/слотами. Вот тебе пример с moveToThread. ---- Что непонятно, спрашивай. Писал в браузере - возможны ошибки. Спасибо, пока сижу перевариваю. Название: Re: QTCPSocket в отдельном потоке. Отправлено: stix357 от Январь 11, 2017, 12:39 stix357, просто QTcpSocket смысла нет переносить в поток. Да и вообще, тебе тут поток не нужен, если работаешь с сокетом сигналами/слотами. Тут у меня затык в том, что клиент с QTcpSocket получает данные непрерывно с контроллера, пока не получит код завершения.Обрабатывать данные надо по мере поступления очередных пакетов. Поэтому приходится на сигнал сокета Код вешать дурную конструкцию типа Код А пока данные принимаются - если в основном потоке, то он висит. Название: Re: QTCPSocket в отдельном потоке. Отправлено: Пантер от Январь 11, 2017, 13:09 waitForReadyRead(900); фтопку, остальное отрабатывает доли секунды.
Название: Re: QTCPSocket в отдельном потоке. Отправлено: stix357 от Январь 11, 2017, 14:32 waitForReadyRead(900); фтопку Не, к сожалению низя, тогда не успевает очередной пакет получить и нагло из цикла выходит на проверке в начале циклаКод waitForReadyRead(500) - это минимально Сам не могу понять почему, разве что сеть WiFi и максимальная скорость канала 56 кбит у радиомодуля при контроллере. Вопрос возник: обязательно сигналы со слотами после создания потомка QTcpSocket связывать во внешней среде, так сказать? я создал потомка Код и у него в конструкторе прописал: Код
и вот эти в отдельном потоке работают нормально Код а вот эти не желают Код
А в основном потоке нормально отрабатывают все Название: Re: QTCPSocket в отдельном потоке. Отправлено: Пантер от Январь 11, 2017, 14:40 > Не, к сожалению низя, тогда не успевает очередной пакет получить и нагло из цикла выходит на проверке в начале цикла
Так ты и должен выйти из цикла, положив то, что пришло во внутренний буфер. Со следующими данными попробуешь распарсить. Как пример, ты ждешь строку. Допустим, строка - это последовательность символов, заканчивающаяся переводом строки. На readyRead ты вычитываешь все, что есть из сокета и ищешь перенос строки - если он есть, обрабатываешь строку, если нету, ждешь дальше. На следующий readyRead ты дочитываешь в буфер все, что пришло и опять производишь поиск. Название: Re: QTCPSocket в отдельном потоке. Отправлено: stix357 от Январь 11, 2017, 15:01 > Не, к сожалению низя, тогда не успевает очередной пакет получить и нагло из цикла выходит на проверке в начале цикла Не, в моем случае этот фокус не пройдет. Я уже пробовал. Тогда радимодуль начинает дурить и вешается. Летит поток байт, и только в самом конце признак окончания передачи.Так ты и должен выйти из цикла, положив то, что пришло во внутренний буфер. Со следующими данными попробуешь распарсить. Как пример, ты ждешь строку. Допустим, строка - это последовательность символов, заканчивающаяся переводом строки. На readyRead ты вычитываешь все, что есть из сокета и ищешь перенос строки - если он есть, обрабатываешь строку, если нету, ждешь дальше. На следующий readyRead ты дочитываешь в буфер все, что пришло и опять производишь поиск. Название: Re: QTCPSocket в отдельном потоке. Отправлено: Пантер от Январь 11, 2017, 15:14 Ты что-то делаешь не так. :)
Название: Re: QTCPSocket в отдельном потоке. Отправлено: Пантер от Январь 11, 2017, 15:14 Попробуй выводить в консоль в hex то, что тебе приходит и проанализируй вручную.
Название: Re: QTCPSocket в отдельном потоке. Отправлено: stix357 от Январь 11, 2017, 17:48 Попробуй выводить в консоль в hex то, что тебе приходит и проанализируй вручную. Это про передачу данных от контроллера? Да я так знаю, что там летит :) Сначала заголовок 17 байт в символах , потом цепочка байтов летит от 00 до FF на канал, затем символьный хвост завершения 19 байт. Просто по связке: Код slotReadyRead - не вызывается второй раз, если убрать из цикла waitForReadyRead(700);//время ожидания очередного пакета Не успевает радиомодуль контроллера кинуть очередной пакет. А радиомудуль гонит пакетами в 738 и второй 281 байт. А у меня клиент смотрит, в цикле, что пусто: bytesAvailable=m_pTcpSocket->bytesAvailable(); И вылетает из цикла. Убегаем на конец slotReadyRead и усе. Радиомодуль долбится, ко мне, как клиенту. Но SIGNAL(readyRead()) не срабатывает. У него (радиомодуля) буфер переполняется (2048 байт) и все, он уходит в аут. Поэтому я заставляю подождать очередной порции - waitForReadyRead(700) Название: Re: QTCPSocket в отдельном потоке. Отправлено: Авварон от Январь 11, 2017, 18:01 Радиомодуль долбится, ко мне, как клиенту. Но SIGNAL(readyRead()) не срабатывает. Какая-то хрень, оно должно попадать в буфер принимающей ОС. Название: Re: QTCPSocket в отдельном потоке. Отправлено: stix357 от Январь 11, 2017, 18:07 Радиомодуль долбится, ко мне, как клиенту. Но SIGNAL(readyRead()) не срабатывает. Какая-то хрень, оно должно попадать в буфер принимающей ОС. Размер изначального пакета неизвестен. Клиент считает, что принял все. И получаю я RST/ACK Название: Re: QTCPSocket в отдельном потоке. Отправлено: Old от Январь 11, 2017, 18:16 А толку-то? если клиент забил на прием? Вот вам и говорят, что у вас сделано неправильно.Размер изначального пакета неизвестен. Клиент считает, что принял все. И получаю я RST/ACK Название: Re: QTCPSocket в отдельном потоке. Отправлено: stix357 от Январь 12, 2017, 07:48 А толку-то? если клиент забил на прием? Вот вам и говорят, что у вас сделано неправильно.Размер изначального пакета неизвестен. Клиент считает, что принял все. И получаю я RST/ACK Если есть желание - посмотрите, где я ошибся. https://drive.google.com/file/d/0Bxq5cvEHXCjyVDA3ZVdyXzR4RGM/view?usp=sharing Прототип клиента Если убрать из кода: Код То все, .... получаю только первый пакет. Скриншот ниже. Клиент (192.168.1.12) говорит - усе я принял, больше не надо. Цитировать 7 4.767455000 192.168.1.12 192.168.1.200 TCP 54 triquest-lm > 32000 [FIN, ACK] Seq=10 Ack=731 Win=65535 Len=0 и отстань от меня серверЦитировать 9 4.769592000 192.168.1.12 192.168.1.200 TCP 54 triquest-lm > 32000 [RST, ACK] Seq=11 Ack=1020 Win=0 Len=0 Цитировать 09:57:00.890 ConnectToServer При включенном ожидании:09:57:00.906 Connected Delay connect: 16 ms 09:57:04.468 Send +WIND:82: 09:57:04.640 bytesAvailable 730 09:57:04.640 Begin +WIND:83:01:06:03 09:57:04.640 bytesAvailable 0 Пусто Delay no Data: 172 ms 09:57:04.640 Total Expected: 18034 09:57:04.640 Total Recive: 730 09:57:04.640 Lost: 17304 Цитировать Log out 10:19:58.609 ConnectToServer 10:19:58.625 Connected Delay connect: 16 ms 10:20:01.703 Send +WIND:82: 10:20:01.953 bytesAvailable 730 10:20:01.953 Begin +WIND:83:01:06:03 10:20:02.125 bytesAvailable 730 10:20:02.125 bytesAvailable 578 10:20:02.296 bytesAvailable 730 10:20:02.468 bytesAvailable 730 10:20:02.468 bytesAvailable 578 10:20:02.640 bytesAvailable 730 10:20:02.812 bytesAvailable 289 10:20:02.812 bytesAvailable 730 10:20:02.812 bytesAvailable 289 10:20:02.968 bytesAvailable 730 10:20:02.968 bytesAvailable 289 10:20:03.140 bytesAvailable 730 10:20:03.312 bytesAvailable 730 10:20:03.312 bytesAvailable 578 10:20:03.484 bytesAvailable 730 10:20:03.687 bytesAvailable 289 10:20:03.687 bytesAvailable 730 10:20:03.687 bytesAvailable 289 10:20:03.828 bytesAvailable 730 10:20:03.828 bytesAvailable 289 10:20:04.000 bytesAvailable 730 10:20:04.000 bytesAvailable 289 10:20:04.156 bytesAvailable 730 10:20:04.328 bytesAvailable 730 10:20:04.328 bytesAvailable 578 10:20:04.500 bytesAvailable 730 10:20:04.671 bytesAvailable 289 10:20:04.671 bytesAvailable 730 10:20:04.671 bytesAvailable 289 10:20:04.890 bytesAvailable 711 10:20:04.890 End +WIND:85:00000000 10:20:04.890 Total Expected: 18034 10:20:04.890 Total Recive: 18034 10:20:04.890 Lost: 0 Название: Re: QTCPSocket в отдельном потоке. Отправлено: Old от Январь 12, 2017, 10:08 Код
Пакет по сети может не прийти полностью или могут прийти сразу несколько пакетов, и все это нужно полноценно разбирать. Пришла только часть пакета - положили ее в буфер и ушли ждать новую порцию данных. Пришли несколько пакетов сразу - обработали их все и если остался не полный пакет, то оставили его в буфере и ушли ждать новую порцию данных. P.S. даже можно прием и разбор пакетов производить в разных местах. Название: Re: QTCPSocket в отдельном потоке. Отправлено: stix357 от Январь 12, 2017, 10:12 Пакет по сети может не прийти полностью или могут прийти сразу несколько пакетов, и все это нужно полноценно разбирать. Пришла только часть пакета - положили ее в буфер и ушли ждать новую порцию данных. А как в ожидание уйти?Пришли несколько пакетов сразу - обработали их все и если остался не полный пакет, то оставили его в буфере и ушли ждать новую порцию данных. Мне изначально неизвестен размер пакета.P.S. даже можно прием и разбор пакетов производить в разных местах. Цитировать Передаваемые данные с сервера АЦП начинаются с признака начала передачи строка +WIN:83:XX:XX:XX, затем без отрыва идут данные сэмплами по байту в HEX формате на канал (значение по каналу от 00 до FF), завершает передачу строка ответа о подтверждении завершения измерений +WIND:85:ХХХХХХХХ А readAll(); это что? Название: Re: QTCPSocket в отдельном потоке. Отправлено: Old от Январь 12, 2017, 10:44 А как в ожидание уйти? Просто выйти из слота обработчика.Мне изначально неизвестен размер пакета. У вас в m_buffer будут все данные, ищите в нем начальный/конечный маркер, или как там вы длину определяете.А readAll(); это что? QByteArray QIODevice::readAll()Сокет наследник QIODevice. Название: Re: QTCPSocket в отдельном потоке. Отправлено: stix357 от Январь 12, 2017, 11:39 А как в ожидание уйти? Просто выйти из слота обработчика.Мне изначально неизвестен размер пакета. У вас в m_buffer будут все данные, ищите в нем начальный/конечный маркер, или как там вы длину определяете.А readAll(); это что? QByteArray QIODevice::readAll()Сокет наследник QIODevice. А как мне узнать сколько я получил в порции(пакете), не пересчитывая каждый раз m_buffer ? Название: Re: QTCPSocket в отдельном потоке. Отправлено: Пантер от Январь 12, 2017, 11:49 > А как мне узнать сколько я получил в порции(пакете), не пересчитывая каждый раз m_buffer ?
Конкретизируй вопрос. Название: Re: QTCPSocket в отдельном потоке. Отправлено: stix357 от Январь 12, 2017, 12:10 > А как мне узнать сколько я получил в порции(пакете), не пересчитывая каждый раз m_buffer ? Ммм ... Вот такая штука по совету Old (Да хранят его боги!) получиласьКонкретизируй вопрос. Код Я хочу узнать сколько прибежало в пакете, дабы посчитать сумму не бегая каждый раз по размеру m_ReadBuffer.size() - вроде это накладно, каждый раз пересчитывается размер массива. m_count=m_pTcpSocket->bytesAvailable()+m_count; но m_pTcpSocket->bytesAvailable() равно 0 :( Название: Re: QTCPSocket в отдельном потоке. Отправлено: Пантер от Январь 12, 2017, 12:17 Вызвать лишний раз QByteArray::size не страшно. Там вообще наверное инлайновый метод.
Название: Re: QTCPSocket в отдельном потоке. Отправлено: Old от Январь 12, 2017, 12:25 но m_pTcpSocket->bytesAvailable() равно 0 :( Это вы после чтения вызываете? Конечно там 0 будет.И не увидел у вас выкусывание уже обработанного пакета из m_buffer? Название: Re: QTCPSocket в отдельном потоке. Отправлено: stix357 от Январь 12, 2017, 12:57 Это вы после чтения вызываете? Конечно там 0 будет. Я полагал, что там все одно цикл чтения, пока пакеты бегут.И не увидел у вас выкусывание уже обработанного пакета из m_buffer? А это черновик пока (отдельная прога для тестирования) без выкусывания :) Еще в поток упихать надо.Название: Re: QTCPSocket в отдельном потоке. Отправлено: Old от Январь 12, 2017, 13:01 Еще в поток упихать надо. Зачем? Там долгая обработка пакета?Название: Re: QTCPSocket в отдельном потоке. Отправлено: stix357 от Январь 12, 2017, 13:16 Еще в поток упихать надо. Зачем? Там долгая обработка пакета?И там в отдельном потоке приходят сигналы еще с 2-х устройств. Встроенные платы АЦП. Одна стробирующие импульсы выдает по прохождению трубы в установке через каждые 50 мм. А труба летит со скоростью 700 мм/сек. А вторая плата АЦП температуру привода выдает. И мне данные со своей части с ними увязать надо. Название: Re: QTCPSocket в отдельном потоке. Отправлено: Пантер от Январь 12, 2017, 13:25 Еще в поток упихать надо. Зачем? Там долгая обработка пакета?И там в отдельном потоке приходят сигналы еще с 2-х устройств. Встроенные платы АЦП. Одна стробирующие импульсы выдает по прохождению трубы в установке через каждые 50 мм. А труба летит со скоростью 700 мм/сек. А вторая плата АЦП температуру привода выдает. И мне данные со своей части с ними увязать надо. Название: Re: QTCPSocket в отдельном потоке. Отправлено: stix357 от Январь 12, 2017, 13:28 У меня есть прога для парсинга данных от автомобильных трекеров. Идет чтение бинарных данных из сокета, парсинг их, формирование xml и выдача его наружу. Одновременно обрабатывается сейчас до 3К трекеров - загрузка процессора меньше 10%. Да, ассинхронка с одним основным потоком. :) А данные трекеры шлют часто, пакетов по 10 в секунду может быть. А тут еще надо параллельно график в Гуе для оператора выводить, по мере поступления данных. Вот и приходится с потоками возится.Название: Re: QTCPSocket в отдельном потоке. Отправлено: Пантер от Январь 12, 2017, 13:30 У меня есть прога для парсинга данных от автомобильных трекеров. Идет чтение бинарных данных из сокета, парсинг их, формирование xml и выдача его наружу. Одновременно обрабатывается сейчас до 3К трекеров - загрузка процессора меньше 10%. Да, ассинхронка с одним основным потоком. :) А данные трекеры шлют часто, пакетов по 10 в секунду может быть. А тут еще надо параллельно график в Гуе для оператора выводить, по мере поступления данных. Вот и приходится с потоками возится.Название: Re: QTCPSocket в отдельном потоке. Отправлено: Пантер от Январь 12, 2017, 13:31 А еще можно разделить на гуй и сервис.
|