LINUX.ORG.RU

QTcpSocket в QThread

 , ,


1

2

Написал вначале QTcpSocket в основном потоке и было все великолепно, стал переносить в поток и понеслось по трубам. Сначала почему-то перестало подключаться по URL(только по IP), я удивился конечно, но думаю ладно. Потом передача данных перестала работать. Стал смотреть в чем дело, а оно только до ConnectingState стало доходить. На серваке accept срабатывает нормально, но передача данных - глухо. В инете советуют вызвать exec на текущем QThread, но когда я это делаю, то у меня сигналы перестают работать. :) Что за ерунда? Спасайте люди добрые.

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

В exec тот самый (не простой) бесконечный цикл, как в играх. Самому класть, это вызывать invokeMethod, а не просить об этом пользователя. :)

BRE ★★ ()
Ответ на: комментарий от Booster

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

BRE ★★ ()
Ответ на: комментарий от BRE

Я снова не понимаю. Если я пошлю бесконечный цикл, то остальным событиям настанет кирдык. Мне нужен и цикл и события одновременно.

Booster ★★ ()
Ответ на: комментарий от Booster

Вы кладете в очередь сообщений событие «вызвать метод А» и запускаете цикл обработки событий (тот самый настоящий бесконечный цикл). Когда дело доходит до этого события - вызывается ваш метод А. Вы делаете необходимые действия, кладете в очередь сообщений еще раз событий «вызвать метод А» и выходите. Цикл повторяется: опрашиваются соекты, обрабатываются события и когда дело доходит до вызова А - все повторяется.

BRE ★★ ()
Ответ на: комментарий от BRE

Так бы сразу и объяснили. :) Метод интересный, если хочется распределять ресурсы между программами, так и вообще красивый. Я не внимательно посмотрел пример anonymous-а. Но опять он не всегда самый лучший, в симуляторах и играх делают именно while(true), который использует ресурсы на всю катушку.

Booster ★★ ()
Ответ на: комментарий от Booster

Это ровно тоже самое. Qt нужен этот бесконечный цикл для своих нужд: обработка событий, пулинг сокетов, обслуживание таймеров... Поэтому, лучше использовать именно его, раз он уже есть, а свой код дергать их него. Кстати, таймер с нулевым интервалом, так же прикрасно с этим справляется - будет вызываться каждую итерацию.

BRE ★★ ()
Ответ на: комментарий от BRE

Ну если все равно, то тогда чем dispatcher->processEvents(QEventLoop::AllEvents) хуже? Нет, мне конечно события больше нравятся именно с архитектурной стороны, но все же. while(true) все-таки думаю немного другое. Одно дело крутить обработку в цикле, лазить в очередь и тут же опять же продолжать работу, так как ничего в ней нет и другое дело постоянно класть в очередь и вынимать из нее. И локальными переменными не шибко попользуешься между вызовами. Кстати попутный вопрос, ничего более нормального чем invokeMethod(this,«string») нету? Вызов по имени это же ахтунг. Сигналы конечно тоже не хочется использовать.

Booster ★★ ()
Ответ на: комментарий от Booster

На самом деле все равнозначно (ну кроме локальных переменных) и каждый подход можно переделать в другой. А вместо invoke можно задействовать таймер с нулевым интервалом. Он будет срабатывать каждую итерацию бесконечного цикла.

BRE ★★ ()
Ответ на: комментарий от BRE

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

Booster ★★ ()
Ответ на: комментарий от Booster

Что за предубеждения? :)

Один раз настроили таймер и он будет каждую итерацию дергать указанный вами метод, в котором вы будете делать то, что собирались делать в своем бесконечном цикле.

BRE ★★ ()
Ответ на: комментарий от Booster

Можно сделать так. Коннектишь сигнал о приходе данных от TCP клиента к слоту. Вызываешь exec(). Сигнал приходит и вызывается слот. В слоте читаешь эти данные и делаешь quit(N).

Как-то так (у меня sslsocket):

void Thread::run()
{
    QSslSocket socket;
    ...
    connect(&socket, SIGNAL(bytesAvailable..., SLOT(slotBytes()));

    while(true)
    {
      switch(exec())
      {
          case 1:
              buffer = socket.readAll();
          break;
      }
    }
}

void Thread::slotBytes()
{
    quit(1);
}

Можно коннектить не к слоту, а сразу к quit(), если кроме прихода данных тебе никаких сигналов не нужно. Кривовато, но что поделаешь.

alex_custov ★★★★★ ()
Последнее исправление: alex_custov (всего исправлений: 1)
Ответ на: комментарий от BRE

Ладно, может попробую, интересно все таки. :) Но вопрос про invokeMethod(this,«string») немного шире. Не буду же я создавать таймер каждый когда хочу послать событие. :) Можно конечно забабахать функцию в которую буду передавать указатель на функцию и уже она будет создавать таймер, но архитектурно это выглядит очень чудно.

Booster ★★ ()
Ответ на: комментарий от Booster

Это все тоже, только вид сбоку. По производительности также, как и обычный бесконечный цикл. :)

BRE ★★ ()
Ответ на: комментарий от Booster

у меня поток данных не такой толстый, несколько сотен Kb/s. Проблем нет, да и не вижу откуда им взяться. Тут оверхед минимальный.

alex_custov ★★★★★ ()
Последнее исправление: alex_custov (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.