Название: QTcoSocket прием данных в отдельном потоке. Отправлено: GPPsoft от Январь 23, 2014, 10:53 Здравствуйте. Как сделать так, чтобы прием и обработка данных выполнялась в отдельном потоке? Спасибо!
Название: Re: QTcoSocket прием данных в отдельном потоке. Отправлено: Fregloin от Январь 23, 2014, 11:38 Поиск в помощь.
Название: Re: QTcoSocket прием данных в отдельном потоке. Отправлено: Serr500 от Январь 23, 2014, 11:38 1) Зачем? Сокеты в Qt асинхронные. Или нужны блокирующие операции?
2) Создаём потомка QThread, запускаем, создаём в нём сокеты, делаем moveToThread. С остальными потоками общаемся посредством сигналов. Название: Re: QTcoSocket прием данных в отдельном потоке. Отправлено: GPPsoft от Январь 23, 2014, 11:45 1) Зачем? Сокеты в Qt асинхронные. Или нужны блокирующие операции? Ну сокет принимает данные и обрабатывает их.... При этом окно зависает. Так не должно быть! Мне надо чтобы я из основного потока мог подключаться-отключаться, а данные которые принимает сокет обрабатывались в отдельном потоке. 2) Создаём потомка QThread, запускаем, создаём в нём сокеты, делаем moveToThread. С остальными потоками общаемся посредством сигналов. Название: Re: QTcoSocket прием данных в отдельном потоке. Отправлено: GPPsoft от Январь 23, 2014, 11:48 Код: connect(this->tcpSocket,SIGNAL(readyRead()),this,SLOT(receiveData())); Название: Re: QTcoSocket прием данных в отдельном потоке. Отправлено: Serr500 от Январь 23, 2014, 11:50 Создаём потомка QThread, запускаем, создаём в нём сокеты, делаем moveToThread. С остальными потоками общаемся посредством сигналов. Что из этого непонятно?Название: Re: QTcoSocket прием данных в отдельном потоке. Отправлено: GPPsoft от Январь 23, 2014, 11:52 Создаём потомка QThread, запускаем, создаём в нём сокеты, делаем moveToThread. С остальными потоками общаемся посредством сигналов. Что из этого непонятно?Название: Re: QTcoSocket прием данных в отдельном потоке. Отправлено: GPPsoft от Январь 23, 2014, 12:52 Ок. Как теперь послать сигнал моему объекту который запустил у себя сокет в отдельном потоке. Вообще как-то не логично и спаггетикодово. Если в java и C# я просто запускал в отдельном потоке чтение потока с сокета, то тут какие-то непонятные наследования и т.д.. Почему так сложно?
Название: Re: QTcoSocket прием данных в отдельном потоке. Отправлено: GPPsoft от Январь 23, 2014, 12:55 Запустил в отдельном потоке вот так. Но как понять когда поток завершиться?
Код: void Session::setClienSocket(QTcpSocket &socket) Еще у меня есть метод: Код: void Session::sendData(const QByteArray &packet) Название: Re: QTcoSocket прием данных в отдельном потоке. Отправлено: thechicho от Январь 23, 2014, 13:58 можно сделать отдельный класс для работы с сокетом. поместить объект этого класса в отдельный поток. если нужны данные для обработки в главном потоке, передавать их туда сигналом.
Код: QThread *thread = new QThread; http://qt-project.org/doc/qt-4.8/qthread.html Название: Re: QTcoSocket прием данных в отдельном потоке. Отправлено: GPPsoft от Январь 23, 2014, 14:43 Пошел таким путем:
.h Код
.cpp Код
При отправке данных, т.е при вызове TCPSocket::sendData(из другого потока), ничего не происходит, даже ошибки нет. Данные тоже не отправляются. Просто тишина. В чем причина? Название: Re: QTcoSocket прием данных в отдельном потоке. Отправлено: thechicho от Январь 23, 2014, 19:09 TCPSocket *tCPSocket = new TCPSocket ;
connect(this, SIGNAL(sendData(QByteArray)), tCPSocket, SLOT(sendData(QByteArray))); QByteArray data; emit sendData(data); class Session { signals: void sendData(QByteArray); }; class TCPSocket : public QThread { public slots: void sendData(QByteArray); } так попробуйте Название: Re: QTcoSocket прием данных в отдельном потоке. Отправлено: GPPsoft от Январь 24, 2014, 03:21 TCPSocket *tCPSocket = new TCPSocket ; connect(this, SIGNAL(sendData(QByteArray)), tCPSocket, SLOT(sendData(QByteArray))); QByteArray data; emit sendData(data); class Session { signals: void sendData(QByteArray); }; class TCPSocket : public QThread { public slots: void sendData(QByteArray); } так попробуйте Название: Re: QTcoSocket прием данных в отдельном потоке. Отправлено: GPPsoft от Январь 24, 2014, 03:38 Код На socket->flush() ловлю QSocketNotifier: socket notifiers cannot be disabled from another thread. Что через сигнал, что через прямой вызов. Как быть? Название: Re: QTcoSocket прием данных в отдельном потоке. Отправлено: GPPsoft от Январь 24, 2014, 05:56 Вот что получилось, вроде то что нужно, но...
.h Код
.cpp Код
Насколько это правильно? И какие могут быть проблемы при таком раскладе? Нашел проблему одну проблему. Если вызвать killConnection(), то поток продолжает работать... Как быть? Название: Re: QTcoSocket прием данных в отдельном потоке. Отправлено: GPPsoft от Январь 24, 2014, 10:05 Какие-то неудобные сокеты в Qt... Ощущение кривоты! Сделал вот так, но теперь непонятно как timeout сделать?
Код: void TCPSocket::onReady() Название: Re: QTcoSocket прием данных в отдельном потоке. Отправлено: Fregloin от Январь 24, 2014, 11:07 неужели так трудно последовать моему совету и порыться в ветке связанной с сетью на форуме? там таких вопросов штук 5 минимум если не больше, и везде есть разъяснения. с конкретными примерами.
Название: Re: QTcoSocket прием данных в отдельном потоке. Отправлено: GPPsoft от Январь 24, 2014, 11:33 неужели так трудно последовать моему совету и порыться в ветке связанной с сетью на форуме? там таких вопросов штук 5 минимум если не больше, и везде есть разъяснения. с конкретными примерами. Вы не поверите. Я уже 2 дня сижу над этим вопросом. И гуглил и искал. Я не нашел решения моей проблемы! :(Название: Re: QTcoSocket прием данных в отдельном потоке. Отправлено: Kurles от Январь 24, 2014, 11:46 Какие-то неудобные сокеты в Qt... Ощущение кривоты! Сделал вот так, но теперь непонятно как timeout сделать? Вы просто не умеете их готовить ) А для таймаутов есть QTimerНазвание: Re: QTcoSocket прием данных в отдельном потоке. Отправлено: kuzulis от Январь 24, 2014, 12:11 GPPsoft,
покамест все неправильно. Читай документацию, смотри пимеры, гугли, работай. А то развелось халявщихов, которые хотят все получить с наскоку, сразу. :) Название: Re: QTcoSocket прием данных в отдельном потоке. Отправлено: GPPsoft от Январь 25, 2014, 03:41 GPPsoft, покамест все неправильно. Читай документацию, смотри пимеры, гугли, работай. А то развелось халявщихов, которые хотят все получить с наскоку, сразу. :) А так? Код
Нихрена прием данных не работает теперь.. Ну и гемморой в Qt с сокетами. Ужас! Название: Re: QTcoSocket прием данных в отдельном потоке. Отправлено: GPPsoft от Январь 25, 2014, 10:05 В продолжение геммороя. Сделал по "феншую", все через сигналы и слоты. Теперь при отправке данных через сигнал славливаю все те же
QSocketNotifier: socket notifiers cannot be enabled from another thread QSocketNotifier: socket notifiers cannot be disabled from another thread .h GUI Код
.cpp GUI Код
.h TCPSocket Код
.cpp TCPSocket Код
Что я делаю не так?! Уже перерыл кучу информации и в google и тут на форуме. Сижу 3 день! Подскажите кто-нибудь, я готов уже заплатить за подсказку. Как мне сделать так, чтобы прием и обработка данных были в отдельном потоке а отправку отключение и подключение к хосту я мог делать в потоке GUI? Спасибо! Название: Re: QTcoSocket прием данных в отдельном потоке. Отправлено: Old от Январь 25, 2014, 10:46 Про невозможность отключения нотифиера сообщение, как я вижу, выдается при попытке отключиться?
А в какой момент получаете сообщение о невозможности включения нотификатора? Название: Re: QTcoSocket прием данных в отдельном потоке. Отправлено: GPPsoft от Январь 25, 2014, 11:07 Про невозможность отключения нотифиера сообщение, как я вижу, выдается при попытке отключиться? При вызове TCPSocket::sendData. Не важно напрямую вызывать или через сигнал. Одна и та же ошибка в логи сваливается.А в какой момент получаете сообщение о невозможности включения нотификатора? Название: Re: QTcoSocket прием данных в отдельном потоке. Отправлено: Old от Январь 25, 2014, 11:13 При вызове TCPSocket::sendData. Не важно напрямую вызывать или через сигнал. Одна и та же ошибка в логи сваливается. Ага точно - увидал. :)Все работает так, как вы написали. Не сердитесь, но вам нужно получше разобраться именно в поддержке ниток в Qt. На форуме очень много раз поднималась эта тема, совсем недавно я пытался на пальцах это рассказать в очередной раз - поищите. Смысл в неправильных типах connect, которые Qt не может корректно определить, в виду того что все соединяемые объекты находятся в контексте одной нитки. Название: Re: QTcoSocket прием данных в отдельном потоке. Отправлено: GPPsoft от Январь 25, 2014, 11:19 При вызове TCPSocket::sendData. Не важно напрямую вызывать или через сигнал. Одна и та же ошибка в логи сваливается. Ага точно - увидал. :)Все работает так, как вы написали. Не сердитесь, но вам нужно получше разобраться именно в поддержке ниток в Qt. На форуме очень много раз поднималась эта тема, совсем недавно я пытался на пальцах это рассказать в очередной раз - поищите. Смысл в неправильных типах connect, которые Qt не может корректно определить, в виду того что все соединяемые объекты находятся в контексте одной нитки. Название: Re: QTcoSocket прием данных в отдельном потоке. Отправлено: GPPsoft от Январь 25, 2014, 11:21 Самое интересное что программа не падает и даже отправляет пакет, но не правильно все это как-то. В логах должно быть чисто :)
Название: Re: QTcoSocket прием данных в отдельном потоке. Отправлено: Old от Январь 25, 2014, 11:21 Что делать и как быть? Нужно решение здесь и сейчас. Код
Название: Re: QTcoSocket прием данных в отдельном потоке. Отправлено: Old от Январь 25, 2014, 11:22 Очень странно что на мой субъективный взгляд работа с сокетами так криво реализована в данном фреймворке. Просто вы с ним не очень разобрались. ;)Но для серьезных применений тоже QtNetwork не использую, предпочитаю boost asio. Название: Re: QTcoSocket прием данных в отдельном потоке. Отправлено: GPPsoft от Январь 25, 2014, 11:26 Что делать и как быть? Нужно решение здесь и сейчас. Код
:) Это что за кривота? Зачем поток в себя же запихивать?! :o Название: Re: QTcoSocket прием данных в отдельном потоке. Отправлено: Old от Январь 25, 2014, 11:27 :) Это что за кривота? Зачем поток в себя же запихивать?! :o Это запись означает, что нужно объект QThread перенести из контекста нитки его создавшей в контекст нитки этого объекта. :)Если пересмотреть архитектуру, то таких вещей делать не придется, но для этого надо вникать. :) Название: Re: QTcoSocket прием данных в отдельном потоке. Отправлено: GPPsoft от Январь 25, 2014, 11:31 :) Это что за кривота? Зачем поток в себя же запихивать?! :o Это запись означает, что нужно объект QThread перенести из контекста нитки его создавшей в контекст нитки этого объекта. :)Если пересмотреть архитектуру, то таких вещей делать не придется, но для этого надо вникать. :) Название: Re: QTcoSocket прием данных в отдельном потоке. Отправлено: Old от Январь 25, 2014, 11:44 А что тут пересматривать? Все же просто. Надо чтобы чтение данных было в отдельном потоке, а работа с сокетом в любом потоке. Например, сделать объект обработчик, который будет взаимодействовать с сокетом и уже эту связку помещать в отдельную нитку. Тогда не придется наследоваться не от сокета, не от нитки.Название: Re: QTcoSocket прием данных в отдельном потоке. Отправлено: GPPsoft от Январь 25, 2014, 11:50 А что тут пересматривать? Все же просто. Надо чтобы чтение данных было в отдельном потоке, а работа с сокетом в любом потоке. Например, сделать объект обработчик, который будет взаимодействовать с сокетом и уже эту связку помещать в отдельную нитку. Тогда не придется наследоваться не от сокета, не от нитки.Название: Re: QTcoSocket прием данных в отдельном потоке. Отправлено: GPPsoft от Январь 25, 2014, 11:58 Постараюсь описать то чего я хочу добиться. Хочу написать некий класс Session который будет работать с сокетом.
Класс должен: 1. Иметь конструктор Session(const QTcpSocket), либо метод setClientSocket(const QTcpSocket) 2. Читать данные в отдельном потоке 3. Иметь метод отключения, аля disconnectFromHost(потокобезопасный) 4. Испускать служебные сигналы(сигнал отключения от хоста и т.д) Далее я наследуюсь этого класса и расширяю его функционал, в зависимости от предназначения. Название: Re: QTcoSocket прием данных в отдельном потоке. Отправлено: Old от Январь 25, 2014, 12:01 Лучше смотреть на саму задачу... что должен этот класс Session делать?
Название: Re: QTcoSocket прием данных в отдельном потоке. Отправлено: GPPsoft от Январь 25, 2014, 12:04 Лучше смотреть на саму задачу... что должен этот класс Session делать? Принимать в качестве параметра конструктора или через метод объект сокета и обрабатывать приходящие данные в отдельном потоке. Могу показать реализацию подобного класса на java. Собственно я и хочу повторить его. Сейчас приведу пример. Название: Re: QTcoSocket прием данных в отдельном потоке. Отправлено: Old от Январь 25, 2014, 12:06 Принимать в качестве параметра конструктора или через метод объект сокета и обрабатывать приходящие данные в отдельном потоке. Могу показать реализацию подобного класса на java. Собственно я и хочу повторить его. Сейчас приведу пример. Не надо яву. :)Абстрагируйтесь от конструкторов и параметров, что нужно сделать. :) Название: Re: QTcoSocket прием данных в отдельном потоке. Отправлено: GPPsoft от Январь 25, 2014, 12:08 Максимально упростил. Оставил только ключевые моменты.
Код
Название: Re: QTcoSocket прием данных в отдельном потоке. Отправлено: GPPsoft от Январь 25, 2014, 12:10 Принимать в качестве параметра конструктора или через метод объект сокета и обрабатывать приходящие данные в отдельном потоке. Могу показать реализацию подобного класса на java. Собственно я и хочу повторить его. Сейчас приведу пример. Не надо яву. :)Абстрагируйтесь от конструкторов и параметров, что нужно сделать. :) Название: Re: QTcoSocket прием данных в отдельном потоке. Отправлено: Old от Январь 25, 2014, 12:13 Думаю проще кодом объяснить. В приведенном примере обработка данных происходит в отдельном потоке. Остальная работа с классом сокета - "потоконезависима". Сейчас нужно уехать, чуть позже... :)Название: Re: QTcoSocket прием данных в отдельном потоке. Отправлено: GPPsoft от Январь 25, 2014, 12:17 Думаю проще кодом объяснить. В приведенном примере обработка данных происходит в отдельном потоке. Остальная работа с классом сокета - "потоконезависима". Сейчас нужно уехать, чуть позже... :)P.S: Буду ждать! Спасибо за проявленный интерес ;) Название: Re: QTcoSocket прием данных в отдельном потоке. Отправлено: Old от Январь 25, 2014, 14:30 Вообщем все что мне нужно, это повторить класс Session который я реализовал на java. Тогда вы его уже практически повторили, осталось отвязать прямой вызов killConnection (использовать сигналы).Другой вариант, это сделать через воркер (обработчик трафика), примерно так: Код
Или можно оформить весь процесс работы в одной функции и использовать QtConcurent, для запуска их в разных нитках. Название: Re: QTcoSocket прием данных в отдельном потоке. Отправлено: GPPsoft от Февраль 05, 2014, 07:05 Вообщем все что мне нужно, это повторить класс Session который я реализовал на java. Тогда вы его уже практически повторили, осталось отвязать прямой вызов killConnection (использовать сигналы).Другой вариант, это сделать через воркер (обработчик трафика), примерно так: Код
Или можно оформить весь процесс работы в одной функции и использовать QtConcurent, для запуска их в разных нитках. Т.е как я понимаю Worker это мой класс который должен обрабатывать входящий трафик? И в данном примере он будет обрабатывать все сигналы от сокета в отдельном потоке? |