crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

kas
  опции профиля:
сообщение 16.6.2010, 18:42
Сообщение #1


Новичок


Группа: Новичок
Сообщений: 8
Регистрация: 16.6.2010
Пользователь №: 1813

Спасибо сказали: 0 раз(а)




Репутация:   0  


здравствуйте! возникла проблема с QTcpSocket. Есть простой клиент, который читает блоками файл и отправляет его на сервер. Сервер: получает данные и записывает их на диск. И возникает такая проблема, что при приеме данных, в некоторый момент времени перестает посылаться сигнал readyRead. При этом данные в буфер сокета записываются и они доступны для чтения. Кто-нибудь сталкивался с такой проблемой? Подскажите в чем может быть причина. Заранее спасибо.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
2 страниц V   1 2 >  
Начать новую тему
Ответов (1 - 9)
ViGOur
  опции профиля:
сообщение 16.6.2010, 21:58
Сообщение #2


Мастер
******

Группа: Модератор
Сообщений: 3296
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 4

Спасибо сказали: 231 раз(а)




Репутация:   40  


В коде.
Покажи код, его думаю немного должно быть...
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
inviZ
  опции профиля:
сообщение 17.6.2010, 5:41
Сообщение #3


Студент
*

Группа: Новичок
Сообщений: 16
Регистрация: 5.6.2010
Пользователь №: 1781

Спасибо сказали: 4 раз(а)




Репутация:   1  


kas, скорее всего в обработчике readyRead ты считываешь из буфера только одно сообщение. А буфер на самом деле может уже содержать несколько. Но лучше покажи код.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
kas
  опции профиля:
сообщение 17.6.2010, 17:09
Сообщение #4


Новичок


Группа: Новичок
Сообщений: 8
Регистрация: 16.6.2010
Пользователь №: 1813

Спасибо сказали: 0 раз(а)




Репутация:   0  


inviZ, спасибо всем за отклик. я уже нашел причину данного глюка.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ViGOur
  опции профиля:
сообщение 17.6.2010, 20:10
Сообщение #5


Мастер
******

Группа: Модератор
Сообщений: 3296
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 4

Спасибо сказали: 231 раз(а)




Репутация:   40  


Так опиши решение для следующих страждуших! :)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Lemon
  опции профиля:
сообщение 15.3.2011, 19:29
Сообщение #6


Новичок


Группа: Новичок
Сообщений: 2
Регистрация: 15.3.2011
Пользователь №: 2505

Спасибо сказали: 0 раз(а)




Репутация:   0  


черт...плохо, что топикстартер не описал решения.
Помогите решить идентичную проблему.
Код потокового класса сервера:
void dbClientThread::run()
{    
    s=new QTcpSocket(this);
    if (s->setSocketDescriptor(ID)) 
    {    
        connect(s, SIGNAL(readyRead()), this, SLOT(incomingData()));                    
        exec();        
    }    
}


void dbClientThread::incomingData()
{    
    int n;
    quint16 res;
    quint16 blockSize=0;    
    QDataStream in(s);    
    in.setVersion(QDataStream::Qt_4_6);
    forever
    {
        n=s->bytesAvailable();
        if (blockSize==0)
        {
            if (n<sizeof(quint16))
                break;
            in>>blockSize;
        }
        
        if (n>=(2*sizeof(quint16)))
        {                
            in>>res;
            switch (res)
            {
            case ReqConnect:
                processingConnection(in);            
                break;
            case ReqExecSQuery:
                executionSQuery(in);
                break;
        }        
        blockSize=0;
    }
}


Далее processingConnection
void dbClientThread::processingConnection(QDataStream &in)
{
    ...
    in>>UserName;
    in>>UserPass;        
    ...
    if (user->ConnectToDataBase(DataSource,SessionName))
    {
        ....
                //отправляет результат
        p=s->bytesAvailable();// Здесь p=0 буффер пуст перед записью ответа            
        out<<quint16(0)<<quint16(ResSUCCESS);
        out.device()->seek(0);
        out<<quint16(msg.size()-sizeof(quint16));
        s->write(msg);
    }
    
}


Теперь код клиента, а именно его readyRead связанный слот
void KP_Client::on_getData()
{
    QDataStream in(&s);
    in.setVersion(QDataStream::Qt_4_6);
    QString status,data;        
    int rows=0,column=0;
    quint16    blockSize=0;
    quint16 res;    
    int n;
    forever 
    {
        n=s.bytesAvailable();
        if (blockSize==0)
        {
            if (n<sizeof(quint16))
                break;
            in>>blockSize;
        }        
        if (n>=(2*sizeof(quint16)))
        {            
            in>>res;
            switch (res)
            {
            case ResSUCCESS:                
                ui.statusBar->showMessage(SUCCESS);    
                p=s.bytesAvailable();//p=0 получает ответ от сервера о подключении
                break;
            case ResFAILED:
                in>>status;
                ui.statusBar->showMessage(status);
                break;
            case ResData:
                    ...
                break;
            }
        }    
        blockSize=0;
    }
}

А собственно проблема в том, что после подключения и отправки рез-та (out<<quint16(0)<<quint16(ResSUCCESS)) у сервера больше не сигналит readyRead(), больше ничего от клиента он не принимает. Подключал слот к stateChanged - состояние не меняется, стабильно = 3(соединение установлено)
(qt 4.7.1 VS 2008)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
PAFOS
  опции профиля:
сообщение 16.3.2011, 9:13
Сообщение #7


Активный участник
***

Группа: Участник
Сообщений: 258
Регистрация: 27.12.2010
Из: Дмитров
Пользователь №: 2309

Спасибо сказали: 29 раз(а)




Репутация:   8  


Может быть не в этом проблема, но все равно у тебя баг:

void dbClientThread::run()
{
s=new QTcpSocket(this);
....

у тебя родительский объект будет экземпляр dbClientThread, который создан в потоке А.
а сам создаваемый объект будет находится в потоке Б

В связи с этим сигналы от QTcpSocket будут обрабатываться в потоке А (или могут вообще до него не доходить, я точно не помню)

Я делаю так:

dbClientThread *thread = new dbClientThread();
thread->start();
thread->moveToThread(thread); // теперь все методы dbClientThread будут обрабатываться в потоке, который был создан в методе run(). т.е. теперь thread обрабатывает сам себя

ну и в методе dbClientThread::run() при создании сокета не указывай родителя.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Lemon
  опции профиля:
сообщение 17.3.2011, 16:35
Сообщение #8


Новичок


Группа: Новичок
Сообщений: 2
Регистрация: 15.3.2011
Пользователь №: 2505

Спасибо сказали: 0 раз(а)




Репутация:   0  


Проблему решило
dbClientThread *thread = new dbClientThread(..., this);
заменить на
dbClientThread *thread = new dbClientThread(...);
хотя преспокойно this стоит в примере
threadfortune
PAFOS большое спасибо за помощь и за исчерпывающее разьеснение :rolleyes:
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
PAFOS
  опции профиля:
сообщение 22.3.2011, 9:37
Сообщение #9


Активный участник
***

Группа: Участник
Сообщений: 258
Регистрация: 27.12.2010
Из: Дмитров
Пользователь №: 2309

Спасибо сказали: 29 раз(а)




Репутация:   8  


Ты уверен что приложение работает так как ты хочешь?))

Поставь в отладчике точку останова на методе void dbClientThread::run()
и на void dbClientThread::incomingData()
когда приложение брякнется, ты увидишь что в методе void dbClientThread::run() у тебя выполняется созданный поток а в методе void dbClientThread::incomingData() выполняется главный)

Получается мнимая многопоточность, товарищ.

Вот мини-проект с доказательствами)


Эскизы прикрепленных изображений
 Р В Р’ Р’ Р’ Р в‚¬Р В РЎВ˜Р В Р’µР Р…ьшено Р Т‘Р С• 72%
Прикрепленное изображение
950 x 662 (48.02 килобайт)
 Р В Р’ Р’ Р’ Р в‚¬Р В РЎВ˜Р В Р’µР Р…ьшено Р Т‘Р С• 70%
Прикрепленное изображение
876 x 739 (54.47 килобайт)
 

Прикрепленные файлы
Прикрепленный файл  Threads.zip ( 2.72 килобайт ) Кол-во скачиваний: 143
 
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 22.3.2011, 11:31
Сообщение #10


фрилансер
******

Группа: Участник
Сообщений: 2943
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


PAFOS, зачётный шрифт :D
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

2 страниц V   1 2 >
Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0


RSS Рейтинг@Mail.ru Текстовая версия Сейчас: 28.5.2025, 12:25