Russian Qt Forum

Qt => Работа с сетью => Тема начата: Fregloin от Май 19, 2011, 17:39



Название: Корректное завершение нескольких клиентских потоков
Отправлено: Fregloin от Май 19, 2011, 17:39
Есть несколько потоков (Qt шных), в которых идет прием по клиентским сокетам.
по нажатию кнопки, нужно корректно завершить все потоки, предварительно закрыв соединение в этих потоках.
Корректен ли такой подход, который привожу ниже:
код потока клиента
Код:
void    QMMNClientThread::run()
{
    mmnClient->connectToServer();
    exec();
}

void     QMMNClient::disconnectFromServer()
{
    fmustReconnect = false;
    if(fsocket->state() == QAbstractSocket::ConnectedState)
    {
        fsocket->close();
        fsocket->waitForDisconnected();
    }
}
при дисконекте клиента, выдерживаю паузу в 2 секунды и делаю реконтект и так вечно пока не надо принудительно завершить работу потока

Код:
void    CEC::startClient()
{
    for(int i=0;i<1;i++) //в будущем тут будет несколько потоков
    {
        if(!mmnClientThread[i]) mmnClientThread[i] = new QMMNClientThread(this); //создаем поток
        mmnClientThread[i]->mmnClient->remoteHost = Host[i]; //задаем к кому подключаться
        mmnClientThread[i]->mmnClient->remotePort = Port[i];
        connect(mmnClientThread[i]->mmnClient,SIGNAL(frameReceived(int)),this,SLOT(data_receive(int))); //обработка принятых данных
        connect(mmnClientThread[i]->mmnClient,SIGNAL(connected(int)),this,SLOT(chan_connected(int)));
        connect(mmnClientThread[i]->mmnClient,SIGNAL(disconnected(int)),this,SLOT(chan_disconnected(int)));
        connect(this,SIGNAL(disconnectClient()),mmnClientThread[i]->mmnClient,SLOT(disconnectFromServer())); //тут я буду слать сигнал потоку что бы он отключил сокет
        mmnClientThread[i]->start(); //запускаю поток
    }
}

void    CEC::stopClient()
{
    for(int i=0;i<1;i++)
    {
        if(mmnClientThread[i])
        {
            emit(disconnectClient()); //шлю сигнал сокету в потоке на принудительное отключение
            disconnect(mmnClientThread[i]->mmnClient); //отключаю все сигналы/слоты
            mmnClientThread[i]->quit(); //закрываю поток
            mmnClientThread[i]->wait(); //жду
            delete mmnClientThread[i]; //удаляю поток
            mmnClientThread[i] = NULL;
        }
    }
}
До этого я не слал сигнал в поток клиента, и иногда прога вылетала, так как сокет успевал подать сигнал о приеме данных, но сам поток уже уничтожен.
После внесения этой коррективы вроде бага на наболюдаю. Подскажите с точки зрения Qt грамотно ли я прибиваю сокет/поток?


Название: Re: Корректное завершение нескольких клиентских потоков
Отправлено: Авварон от Май 19, 2011, 20:56
я не вижу дисконнект клиент
эмит - это макрос, к-ый ничего не делает, просто для красоты.
следовательно, вы вызываете ф-ию напрямую и что-то мне подсказывает что не из того потока
зачем тут вообще больше 1го потока? сокеты все из себя и так асинхронные


Название: Re: Корректное завершение нескольких клиентских потоков
Отправлено: Fregloin от Май 20, 2011, 12:45
вообще по плану будет 5 подключений к разным машинам, все одновременно будут получать данные с серверов. данные идут потоком, непрерывно каждые 250 мсек кадры по 4-8Кб. помимо того, в основном потоке еще идёт прорисовка в GraphicsScene около 1000 объектов + логика расчета состояний. поэтому резонно хотя бы чтение по сокетам перенести в одельные потоки. В целом пока этот механизм работает нормально.


Название: Re: Корректное завершение нескольких клиентских потоков
Отправлено: Авварон от Май 20, 2011, 16:32
Данные приходят от сервера, попадают в буфер сокета, Qt кидает сигнал об этом. Вы копируете из буфера в свои структуры. Зачем тут больше 1го потока?