Russian Qt Forum

Qt => Многопоточное программирование, процессы => Тема начата: RedDog от Февраль 14, 2011, 12:12



Название: Вся работа сокета в отдельном потоке
Отправлено: RedDog от Февраль 14, 2011, 12:12
На основе примера из справки пытаюсь сделать многопоточный сервер:
Код:
class NetworkServer : public QTcpServer
{
    Q_OBJECT
public:
    explicit NetworkServer(QObject *parent = 0);
private:
    void incomingConnection(int handle);
};

void NetworkServer::incomingConnection(int handle)
{
    SocketWorkThread *thread = new SocketWorkThread(this, handle);
    thread->start();
}

Поток:

Код:
class SocketWorkThread : public QThread
{
    Q_OBJECT
public:
    explicit SocketWorkThread(QObject *parent = 0,
                              int _socketDescriptor = 0);
    void run();

private:
    QTcpSocket *socket;
    int m_socketDescriptor;

public slots:
    void on_recieveCommand();
};

void SocketWorkThread::run()
{
    socket = new QTcpSocket(this);
    connect(socket, SIGNAL(readyRead()),
            this, SLOT(on_recieveCommand()));
    socket->setSocketDescriptor(m_socketDescriptor);
    socket->moveToThread(this);
    exec();
}

void SocketWorkThread::on_recieveCommand()
{
  // тут большая ф-я по обработке данных и работе с клиентом
}
В примере все тяжелая работа происходит в QThread::run(), но у меня сокет должен в отдельном потоке сначала слушать данные от клиента, а потом передавать ему данные, поэтому в run() не соображу как это поместить.
В моем коде не получается никакого отдельного потока, GUI "висит" при работе сокета. Как тут быть?


Название: Re: Вся работа сокета в отдельном потоке
Отправлено: SimpleSunny от Февраль 14, 2011, 12:39
В конструкторе добавьте такую строчку

Код
C++ (Qt)
SocketWorkThread(QObject *parent = 0, int _socketDescriptor = 0)
   : QThread(), socketDescriptor(_socketDescriptor)
{
   moveToThread(this);
}


Название: Re: Вся работа сокета в отдельном потоке
Отправлено: RedDog от Февраль 14, 2011, 12:49
Не помогает, ГУИ все равно висит


Название: Re: Вся работа сокета в отдельном потоке
Отправлено: SimpleSunny от Февраль 14, 2011, 12:55
А в консоли есть какие-то сообщения об ошибках?


Название: Re: Вся работа сокета в отдельном потоке
Отправлено: BRE от Февраль 14, 2011, 13:14
Попробуй так:
Код
C++ (Qt)
void SocketWorkThread::run()
{
   socket = new QTcpSocket( 0 ); // <<< parent = 0
   connect(socket, SIGNAL(readyRead()),
           this, SLOT(on_recieveCommand()));
   socket->setSocketDescriptor(m_socketDescriptor);
   socket->moveToThread(this); // <<< Эта строка не нужна. Сокет уже создан в контексте этого потока.
   exec();
}
 

Эта тема поднималась уже не раз - пользуйтесь поиском.


Название: Re: Вся работа сокета в отдельном потоке
Отправлено: RedDog от Февраль 14, 2011, 14:41
Попробуй так:
Не дало результатов
Эта тема поднималась уже не раз - пользуйтесь поиском.
Я чет как то затрудняюсь в подборе ключевых слов по данной теме :-\


Название: Re: Вся работа сокета в отдельном потоке
Отправлено: BRE от Февраль 14, 2011, 15:13
Не дало результатов
Код
C++ (Qt)
SocketWorkThread( int _socketDescriptor )
   : QThread( 0 ), socketDescriptor(_socketDescriptor)
{
  ...
}
 

Вроде Qt должен был в консоль сообщения по этому поводу сыпать.


Название: Re: Вся работа сокета в отдельном потоке
Отправлено: BRE от Февраль 14, 2011, 15:14
Я чет как то затрудняюсь в подборе ключевых слов по данной теме :-\
thread QTcpSocket


Название: Re: Вся работа сокета в отдельном потоке
Отправлено: RedDog от Февраль 14, 2011, 16:18
Я чет как то затрудняюсь в подборе ключевых слов по данной теме :-\
thread QTcpSocket

Как оказалось не там и не тем искал... гугол выдал нужный результат
http://www.prog.org.ru/topic_3891_0.html
Суть в кратце:
Необходимо создать отдельный объект, в котором будет работать сокет, в этом объекте связать все сигналы и слоты с сокетом, а уже в потоке в run() создать экземпляр этого объекта.
В такой схеме, напрягает лишь одно - сигналы до главного потока идут "через 10-е руки".
В общем все получилось, всем спасибо.