Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум на CrossPlatform.RU _ Qt Ввод/Вывод, Сеть. Межпроцессное взаимодействие _ Ожидание чтения и сокращение загрузки процессора.

Автор: dasV 13.3.2009, 17:47

Добрый день уважаемые. Я новичок в qt да и в c++ поэтому бейте меня и посылайте на RTFM.


Есть Вот такой код

QString M_class::ReadSocket()
{
    QTime TimeOut;
    TimeOut.start();
    while(!socket.waitForReadyRead())
        {    
            QCoreApplication::processEvents();
            if(TimeOut.elapsed()>=6000)
            {
                return(0);
            }
        }
    return(socket.readAll());
}


Так вот он создает нагрузку на процессор, а если ожидание затягивается, то и вовсе становится неприятно что я такой вот пожиратель тактов.

Можно ли справить ситуацию?? Сразу оговорюсь что программа консольная и в ней нет Q_OBJECT с вызовом QTimer::timeout ()

Да еще вопрос, к месту ли тут QCoreApplication::processEvents()???

С уважением

Автор: kwisp 13.3.2009, 17:52

dasV,
что мешает включить в конольную прогу Q_OBJECT ???
и использовать для чтения сокета сигналы и слоты тогда можно.

Цитата(dasV @ 13.3.2009, 17:47) *
к месту ли тут QCoreApplication::processEvents()???

точно нет в этой ситуации.

Автор: Litkevich Yuriy 13.3.2009, 17:56

dasV, цыклы лучше в отдельный поток помещать у них приоритет задать можно.

Цитата(kwisp @ 13.3.2009, 20:52) *
точно нет в этой ситуации.
если человуку захочется программу закрыть, окно командной строки, то без этой строчки невыйдет.

Автор: LE0N 13.3.2009, 17:56

virtual bool waitForReadyRead ( int msecs = 30000 )
Как ты думаешь...А зачем там задан параметр msecs ?

Автор: dasV 13.3.2009, 19:24

Хм, написал вот что

QString Sms_class::ReadSocket()
{
    QTextCodec::setCodecForTr(QTextCodec::codecForName("CP-1251"));
    QTextCodec *concodec = QTextCodec::codecForName("CP-866");
    QTextStream out(stdout);
    out.setCodec(concodec);

    QTime TimeOut;
    TimeOut.start();
    
    if(socket.waitForReadyRead(60000)==false)
        {    out<<"MSG : Time - "<<TimeOut.elapsed()<<endl;
            return(0);
        }
    out<<"MSG : Time - "<<TimeOut.elapsed()<<endl;
    return(socket.readAll());
}


Результат работы

MSG : Write GET //запрос и переход на ожидание ответа
MSG : Wait response from server
MSG : Time – 5598 // то есть мы ждали но дождались ответа
**** Тут могла быть Ваша реклама****
MSG : Write GET // опять запрос и переход на ожидание ответа
MSG : Time – 10 // фактически не ждали, сразу выдали таймаут
MSG : Error CloseSession! //тут должен быть ответ, то есть некое число

Но из за
tmp=ReadSocket();

    if(tmp.isNull ()==true)
    {
        out<<"MSG : Error CloseSession!!"<<tmp<<endl;
        return(false);
    }

В вызывающей функции числа нет, следна это не 0 а именно «string is null»

Может я, что то не углядел?

Автор: LE0N 13.3.2009, 19:51

QString QIODevice::errorString () const ?
Кто должен отлаживать, ты или МЫ?

Автор: Litkevich Yuriy 13.3.2009, 20:24

Цитата(dasV @ 13.3.2009, 22:24) *
if(tmp.isNull ()==true)
отвыкай от этой записи, сравнение с булевой константой излишне и некрасиво

Цитата(dasV @ 13.3.2009, 22:24) *
следна это не 0 а именно «string is null»
переменная tmp какого типа?

Автор: kwisp 13.3.2009, 20:25

Цитата(Litkevich Yuriy @ 13.3.2009, 17:56) *
если человуку захочется программу закрыть, окно командной строки, то без этой строчки невыйдет.

там же таймаут вроде есть. должно по Ctrl-C завершиться. хотя если есть в программе корректный выход то его не заюзаешь.

а так вообще не пояснено почему сигналы и слоты использовать нельзя..
почему???

Цитата(Litkevich Yuriy @ 13.3.2009, 20:24) *
переменная tmp какого типа?

Цитата(dasV @ 13.3.2009, 19:24) *
tmp=ReadSocket();
Цитата(dasV @ 13.3.2009, 19:24) *
QString Sms_class::ReadSocket()

QString получается.

Автор: Litkevich Yuriy 13.3.2009, 20:26

Цитата(kwisp @ 13.3.2009, 23:24) *
должно по Ctrl-C завершиться
если их будет кому обрабатывать.

Цитата(kwisp @ 13.3.2009, 23:24) *
а так вообще не пояснено почему сигналы и слоты использовать нельзя..
почему???
согласен лучше сразу похорошему делать, потом работы будет меньше.

Автор: LE0N 13.3.2009, 20:33

Цитата
переменная tmp какого типа?

Очевидно же - QByteArray ))

Автор: dasV 13.3.2009, 22:16

А я и не говорил что нельзя, мне просто неудобно, из за непонимания логики работы программы при использовании слотов.

Мне необходимо допустим три раза вызвать запись, три раза прочитать и при этом каждый раз я получаю разные данные, которые необходимо обработать разными методами. В результате я не понимаю, что мне надо делать в при вызове слота readyRead, откуда вызвано, куда что передавать,… понятно когда GUI приложение, жмякнул на кнпку (соединится) я соединился, жмякнул на кпопку (Послать) я и послал, жмякнул выход я рас соединился.

А в консоли, что мне делать?? Я все и по порядку и делаю, при этом смысла в слотах я не вижу.

2_LE0N спасибо, буду думать..
2_Litkevich Yuriy спасибо за замечание, буду отвыкать.

С уважением

Автор: kwisp 13.3.2009, 22:27

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

Цитата(dasV @ 13.3.2009, 17:47) *
программа консольная и в ней нет Q_OBJECT

я решил что кто то или что то ограничило пути решения.
все таки в толк не возьму в чем разница консольное приложение или гуёвое в гуёвом понятно в консольном не понятно...как так?
давай разбираться.

Автор: Litkevich Yuriy 13.3.2009, 22:32

Цитата(dasV @ 14.3.2009, 1:16) *
А в консоли, что мне делать?? Я все и по порядку и делаю, при этом смысла в слотах я не вижу.
ну в консоли же не умерает объектно-ориентированное програмирование. У меня есть программа консольная которая опрашивает аппаратуру через COM-порт, сигналы и слоты мне очень помогли, без них было бы мение удобно работать.

Автор: dasV 14.3.2009, 20:01

Задача такова, я должен послать на сервер запрос авторизации, сервер мне ответит (тут я должен распарсить что он мне ответил) если это нормальный ответ, я посылаю запрос на выдачу мне нужной информации, при этом сервер мне отвечает xml строкой где я ищу нужные мне строки, вывожу на экран и опять посылаю запрос на закрытие соединения, опять ответ опять корректно закрыли или нет. Это простейший случай который реализован без Q_OBJECT шаг за шагом.

В результате я не могу понять ну вот я в конструкторе или в другом месте создал

QObject::connect(&socket, SIGNAL(encrypted()),this, SLOT(socketEncrypted()));
QObject::connect(&socket, SIGNAL(readyRead()),this, SLOT(socketReadyRead()));
    
set_encrypted_connect(); //socket.connectToHostEncrypted(ssl_host,ssl_port);


В результате после соединения с хостом я вызову
socket.write(get.toUtf8()+ "\r\n"); //тут get="GET что то там ";


А после будет получен сигнал readyRead() который вызовет слот socketReadyRead() в результате будет прочитана строка socket.readAll() “Я получаю ответ от сервера и допустим …ура!!! Все хорошо!!” а дальше что?? Как мне указать программе, что пора получать данные, после чего закрыть соединение??
Ну допустим я после чтения в функии socketReadyRead опять сделаю запрос

socket.write(get.toUtf8()+ "\r\n");

Но после этого опять будет вызван socketReadyRead() и так по кругу… вот тут меня и клинит!!!


Может книгу порекомендуете ?? С удовольствием почитаю =)

С уважением

Автор: kwisp 14.3.2009, 20:27

dasV,
существует такой метод или "агрегат" униерсальный для таих задач. называется машина состояний.
есть состояния твоей проги. есть состояния сокета есть состояния данных и т.д и т.п..
состояния это обычно перечисляемый тип. и переменная в классе. в зависимости от действий в программе переключай состояния. при событиях проверяй в каком состоянии находишься и действуй.

Цитата(dasV @ 14.3.2009, 20:01) *
А после будет получен сигнал readyRead() который вызовет слот socketReadyRead()

не пойму почему он вызовется. он вызывается не в тот момент когда сокет свободен а когда с другой стороны в него данные послали.

Автор: dasV 14.3.2009, 20:54

2_ kwisp Спасибо, буду думать, а это не оно ли случаем?
http://ru.wikipedia.org/wiki/Автоматное_программирование

Насчет, почему вызовется, потому как мы сделали socket.write при этом сервер нам будет возвращать данные, чего мы и ожидаем, ну по крайней мере в примерах именно так реализовано.

Автор: kwisp 15.3.2009, 9:16

Цитата(dasV @ 14.3.2009, 20:54) *
а это не оно ли случаем?

да оно. :)

Автор: dasV 26.3.2009, 19:33

Доброго времени суток уважаемые.
Сделал как и сказано было, однако возникла проблема, если первый раз я произвожу запись из функции socketEncrypted() после чего читаю вполне нормально данные полученные от сервера, то второй раз, данные записать не удается. Точнее функция возвращает мне количество записанных данных, однако на деле ничего на сервер не приходит.

Может кто то сталкивался с такой проблемой?

Раскрывающийся текст

void ssl_class::socketReadyRead()
{

    QString tmp;
    bool ok;
    int i; // он вообще то не оч нужен, но так..пусть будет =)

    switch(state)
    {
       case StartSession:
       {
        tmp=xmlParser(socket.readAll());
        SessionID=tmp.toInt(&ok, 10);
        if(!ok)
        {
            if(SessionID<=0)
            {
                //MSG : ошибка логин или пароль, не верны
                emit finish();
            }
        }
        tmp="GET "+get+"/CloseSession?SessionID="+ QString::number(SessionID)+" \r\n";
        i = socket.write(tmp.toUtf8());

        if(i==-1)
        {
            //MSG : Ошибка при записи
        }
        else
        {
            //MSG : записали много байт
        }

        state=CloseSession;

           break;
       }

       case CloseSession:
       {
            tmp=xmlParser(socket.readAll());
            SessionID=tmp.toInt(&ok, 10);
            if(!ok)
            {
                if(SessionID==0)
                {
                    //MSG : все хорошо
                }
            }
            emit finish();
           break;
       }
    }
}




Заранее спасибо.

Автор: igor_bogomolov 26.3.2009, 23:51

Может я уже немного не в тему и не вовремя, но я бы использовал другую конструкцию. Предлогалось уже использовать сигналы и слоты, так и не понял почему этого не сделали. Я бы использовал следущую конструкцию:

Создал свой класс, наследник от QThread:

class ThreadSocket : public QThread
{
    Q_OBJECT
    
    ...
    QTcpSocket *socket;
    QMutex mutex;
    QWaitCondition cond;
    QByteArray DataIn;
    ...    
protected:
    void run();
    ...

private slots:
    void readSocket();
    ...
}


Переопредилил Run следущим образом:
void ThreadSocket::run()
{
    const int Timeout = 6 * 1000;
    
    emit SendServer("first_command"); // отправляем данные для записи в соккет
    mutex.lock();
    if ( cond.wait(&mutex, Timeout) ) { // ожидаем ответ. Если получили, разбираем данные и отправляем след. команду
        ... //  разбираем данные, в общем любые требуемые действия.
        DataIn.clear();
        
        emit SendServer("second_command"); // отправляем данные для записи в соккет
        if ( cond.wait(&mutex, Timeout) ) {// ожидаем ответ.
            ... //  разбираем данные, в общем любые требуемые действия.
            DataIn.clear();
            
            // и т.д.
            ...
            ...
            ...
            ...
            
        } else {
            emit displayMessage("Timeout №2"); // отправляем сообщение об ошибке.
        }
    } else {
        emit displayMessage("Timeout №1"); // отправляем сообщение об ошибке.
    }
    mutex.unlock();
            ...
}



SLOT. Чтение динных с сервера:
void ThreadSocket::readSocket()
{
    if ( socket->canReadLine() ) {
        mutex.lock(); // -----------------------
        DataIn = DataIn + socket.readAll();//     |   mutex здесь впринципе не нужен )))
        mutex.unlock(); //-----------------------
        cond.wakeOne();
    }
}


Надеюсь мысль понятна :rolleyes:


[offtop]
Простите, но почему я не могу редактировать сообщения?
И как сделать Раскрывающийся текст. А то я обрамил все в тег "Скрытый текст", думал что это оно, теперь и не знаю, читается ли код?
[\offtop]

Автор: igor_bogomolov 27.3.2009, 0:44

Дополнительно(конкретно по вопроссу)

Цитата(dasV @ 26.3.2009, 19:33) *
второй раз, данные записать не удается. Точнее функция возвращает мне количество записанных данных, однако на деле ничего на сервер не приходит.

Добавьте
socket.flush();

Автор: igor_bogomolov 27.3.2009, 1:18

И еще. Сигнал readyRead () испускается каждый раз, как доступны новые данные для чтения. Увырены ли Вы, делая socket.readAll() , что все данные которые Вы ожидаете доступны для чтения. Лучьше всегда делать проверку, например функцией bytesAvailable () или canReadLine ().

Цитата
qint64 QAbstractSocket::bytesAvailable () const [virtual]

Возвращает число присланных байт, которые ждут прочтения.

Цитата
bool QAbstractSocket::canReadLine () const [virtual]

Возвращает true, если строка данных может быть прочитана из сокета; в противном случает возвращает false.

Автор: Litkevich Yuriy 27.3.2009, 1:45

Цитата(igor_bogomolov @ 27.3.2009, 2:51) *
Простите, но почему я не могу редактировать сообщения?
после 20 сообщений появится такая возможность.
Цитата(igor_bogomolov @ 27.3.2009, 2:51) *
И как сделать Раскрывающийся текст.
http://www.forum.crossplatform.ru/index.php?showtopic=1455

Автор: igor_bogomolov 27.3.2009, 3:33

Litkevich Yuriy Спасибо. С раскрывающимся текстом разобрался, просто был невнимателен. А с редактированием это плохо, жесткие у вас правила.

Автор: Litkevich Yuriy 27.3.2009, 4:27

Цитата(igor_bogomolov @ 27.3.2009, 6:33) *
А с редактированием это плохо, жесткие у вас правила.
попрошу админа, чтобы дал тебе такую возможность уже сейчас

Автор: AD 27.3.2009, 9:48

Цитата(LE0N @ 13.3.2009, 19:51) *
QString QIODevice::errorString () const ?
Кто должен отлаживать, ты или МЫ?

LEON, уважай собеседника и будь вежлив. Все мы были новичками. Если человек чего-то не понимает, объясни, а не груби!

Автор: LE0N 27.3.2009, 12:49

Цитата
LEON, уважай собеседника и будь вежлив. Все мы были новичками. Если человек чего-то не понимает, объясни, а не груби!

Я очень редко выхожу за рамки. Это - в рамках. Неуважением здесь и не пахнет. Если вас, что то не устраивает - айда в личку - обсудим....

Автор: dasV 27.3.2009, 19:45

Всем спасибо за ответы.
Сделал socket.flush (); однако ничего не изменилось. Решил посмотреть состояние socket и выяснилось, что оно все время QAbstractSocket::ConnectedState то есть вроде как ошибок и нет, правда если после socket.write сделать socket.flush (); то состояние меняется на QAbstractSocket::UnconnectedState, вообще не понятно ничего =(

Так же подумал, что мол не все прочитали и пишем, поэтому сделал так

out<<socket.bytesAvailable()<<endl;
tmp=xmlParser(socket.readAll());
out<<socket.bytesAvailable()<<endl;


в результате все нормально в начале было 308 байт стало 0.

2_LE0N сделал как и уважаемый просил
QObject::connect(&socket, SIGNAL(sslErrors(QList<QSslError>)),this, SLOT(socketErrors(QList<QSslError>)));
результат к сожалению тот же, слот не вызывается.

Хотел бы спросить igor_bogomolov, скажите, вот сколько у нас байт на чтениемы, можем узнать, с помощью функции bytesAvailable а сколько должны (то есть сколько реально должны прочитать) можно ли узнать? То есть сервер нам говорит, я пришлю 500 байт, я вижу, что их 200 и не читаю, дожидаюсь следующей порции данных. Такое возможно?

Насчет canReadLine то же понятНО тут придется писать while(socket.canReadLine()) который опять может привести к поеданию тактов от чего и уходили.

Насчет отдельных QThread я понял, однако пока их не изучал и не лезу туда, но много видел советов использовать их в своих программах.

Может еще что то придумать??

Спасибо.

Автор: BRE 27.3.2009, 20:27

Цитата(dasV @ 27.3.2009, 19:45) *
Хотел бы спросить igor_bogomolov, скажите, вот сколько у нас байт на чтениемы, можем узнать, с помощью функции bytesAvailable а сколько должны (то есть сколько реально должны прочитать) можно ли узнать? То есть сервер нам говорит, я пришлю 500 байт, я вижу, что их 200 и не читаю, дожидаюсь следующей порции данных. Такое возможно?

Насчет canReadLine то же понятНО тут придется писать while(socket.canReadLine()) который опять может привести к поеданию тактов от чего и уходили.

Пускать while не надо. Смотри как будет происходить асинхронный обмен. Сервер говорит пришлю 500 байт, далее он начинает слать эти данные. Приходит первая порция данных (200 байт), вызывается слот readyRead, в нем ты вычитываешь 200 байт в буфер, понимаешь, что это не все данные и выходишь из слота, чуть позже приходят оставшиеся 300 байт, опять вызывается слот readyRead, в нем ты дочитываешь оставшиеся данные в тот же буфер, понимаешь что пришли все данные и обрабатываешь их (посылаешь сигнал что пакет с данными получен или переключаешь состояние на обработку этого пакета).

Автор: LE0N 27.3.2009, 23:24

Цитата
Так же подумал, что мол не все прочитали и пишем, поэтому сделал так

А с чего ты взял, что остольные данные придут сразу после того, как ты прочитал ВСЁ, что есть на данный момент ?
Цитата
LE0N сделал как и уважаемый просил

Имелось ввиду, что на момент того, как ты обнаруживаешь ошибку, т.е. ситуация, которая складывается на данный момент - является ошибочной для твоего понимания, можно проверить весь возможный функционал твоей программы на ошибки - это называется процессом отладки. А не какие то слоты подключать....Это тоже можно, но делать это надо тогда, когда ты точно знаешь чего делаешь.
Цитата
а сколько должны (то есть сколько реально должны прочитать) можно ли узнать? То есть сервер нам говорит, я пришлю 500 байт, я вижу, что их 200 и не читаю, дожидаюсь следующей порции данных. Такое возможно?

Для того, что бы читать ТОЛЬКО нужное количество данных, обычно, пишут свой небольшой протокол. Например - в первых двух-8 байтах(в зависимости от максимального размера информации, которую надо передать) передают размер этой информации.
Цитата
Насчет отдельных QThread я понял, однако пока их не изучал и не лезу туда, но много видел советов использовать их в своих программах.

Может еще что то придумать??

Есть очень хорошая чья то цитата...
- Пиши как можно проще, тяжело получится само....
Так что реализуй пока без отдельных процессов и прочей байды...Не лезь в дебри. Рановато....

Автор: igor_bogomolov 28.3.2009, 1:29

Цитата(dasV @ 27.3.2009, 19:45) *
Хотел бы спросить igor_bogomolov, скажите, вот сколько у нас байт на чтениемы, можем узнать, с помощью функции bytesAvailable а сколько должны (то есть сколько реально должны прочитать) можно ли узнать?

Нет, не можем. Этот метод возвращает количество байт доступных для чтения в данный момент. Вы сами должны знать свой протокол общения с сервером. Т.е., как уже говорилось, либо сервер в заголовке возвращает количество байт которые он собирается передать, либо есть какая то завершающая последовательность, по которой можно определить что все данные получены. Если вы протокола не знаете, и сервер просто сыпет данные, то остается только предпологать, что все данные получены, например по таймауту. Т.е. если в течении некоторого времени данные больше не поступают, делаем вывод что сервер все передал.

Цитата(dasV @ 27.3.2009, 19:45) *
Насчет canReadLine то же понятНО тут придется писать while(socket.canReadLine()) который опять может привести к поеданию тактов от чего и уходили.

QTcpSocket - предоставляет неблокирующий интерфейс. Т.е. если вы используете сигналы и слоты, никакого блокирования не происходит. Единственное while, как уже сказали, совершенно не нужен. Вызвали в слоте canReadLine(), если возвращает false, просто выходим. Как придут новые данные, попадем снова в наш слот, проверим canReadLine(), если true, считаем строку целиком. Таким образом и ход выполнения программы не останавливается и лишние такты мы не жрём. :rolleyes:

Цитата(LEON) *
Так что реализуй пока без отдельных процессов и прочей байды...Не лезь в дебри. Рановато....

А когда тогда не рано? Если никуда не лездь, то ничему и не научишься. Нужно стремиться к новым знаниям :rolleyes:

Автор: LE0N 28.3.2009, 10:39

Цитата
А когда тогда не рано? Если никуда не лездь, то ничему и не научишься. Нужно стремиться к новым знаниям

Ни кто с этим не спорит. Но на мой взгляд, он должен сначала решить эту же задачу без наворотов...

Автор: dasV 6.4.2009, 11:43

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

igor_bogomolov я сделал (точнее попытался сделать) как Вы и сказали через canReadLine() однако столкнулся с недопониманием (не докурил) вот какого момента (информацию о котором не смог найти).

Скажите если мы не можем прочитать строку, это может значить что мы прочитали все что нам прислали?
То есть нам надо определить, или мы действительно не можем прочитать строку (а значит, нам надо бы подождать) или второй вариант, нам уже все прислали и надо обрабатывать строки?

Вторая проблема вытекающая из первой, с которой столкнулся, это то, что на последнюю строку canReadLine() выдает false, хотя если вызывать принудительно ReadLine() выдает последнюю строку... не понятно так как если подождать, socketReadyRead() повторно не вызывается =(.

Спасибо.

Автор: igor_bogomolov 6.4.2009, 12:19

У вас хоть какой-то протокол общения с сервером есть? Не возвращается ли в самом начале сколько байт будет передано? Или завершающая последовательность какая-нибудь есть? Или вы отправляете команду и сервер начинает сыпать неизвестно чего и сколько

// add
Можно убрать проверку canReadLine, и считывать все что приходит в буфер. При этом должен быть какой-то таймаут. Если в течении этого таймаута ничего не пришло, то считаем что все данные получены, и идем на оьработку

Автор: dasV 6.4.2009, 12:44

Добрый день.

Протокол общения обычный http, я знаю, сколько мне передадут или должны передать (так как есть Content-Length: который я обрабатываю) и получаю длину, которую пока не обрабатываю.

Но это все ерунда полная (хотя и интересная), мне важно узнать, по какой причине socket не пишет на сервер второй раз =(

Спасибо.

Автор: igor_bogomolov 6.4.2009, 12:57

Цитата(dasV @ 6.4.2009, 13:44) *
я знаю, сколько мне передадут или должны передать
Так если вы знаете сколько быйт вы должны принять в ответ на свою команду, то проблем вообще быть не должно. Просто отслеживаете количество принятых данных и все.
Цитата(dasV @ 6.4.2009, 13:44) *
Но это все ерунда полная (хотя и интересная), мне важно узнать, по какой причине socket не пишет на сервер второй раз =(
Вот тут я ничего не понял. О чем речь, что за ерунда? Что значит не пишет второй раз? Сформулируйте вопросс точнее. Еще лучьше коды приложите.

Автор: dasV 6.4.2009, 13:25

Да я действительно не очень…ммм, не очень корректно написал.

Проблема моей программы (и соответственно моей безграмотности) заключается в том, что в случае повторной отсылки GET запроса на сервер (state == CloseSession) , ничего не происходит, то есть запрос просто не передается!

qlonglong ssl_class::WriteMsgToSrv()
{
    QString tmp;        //не обязательно, убрать.
    qlonglong i;            //не обязательно, убрать.
    switch(state)
    {
        case(StartSession):
        {
            tmp="GET "+get+"/StartSession?Login="+login+"&Password="+password+"&Gmt=3 \r\n";
            break;
        }
        case(CloseSession):
        {
            tmp="GET "+get+"/CloseSession?SessionID="+ QString::number(SessionID)+" \r\n";
            break;
        }
    }
i= socket.write( tmp.toUtf8() );
socket.flush ();                
return( i );
}


Я к сожалению не хочу позорится, если Вы дадите почту я перешлю весь код.

Спасибо.

Автор: Litkevich Yuriy 6.4.2009, 13:29

Цитата(dasV @ 6.4.2009, 17:25) *
Я к сожалению не хочу позорится,
да ладно тебе.

Автор: trdm 6.4.2009, 14:59

Цитата(Litkevich Yuriy @ 6.4.2009, 14:29) *
Цитата(dasV @ 6.4.2009, 17:25) *
Я к сожалению не хочу позорится,
да ладно тебе.

да ладно, нормальный комплекс. Самое удивительное, он полезный :)
плохо то, что помочь не могу, а код посмотреть хочется, тоже с такой задачОЙ бду заморачиваться...

Автор: igor_bogomolov 6.4.2009, 15:53

Приложите еще хотябы код метода в котором вы считываете данные с соккета.

Цитата(dasV @ 6.4.2009, 14:25) *
case(CloseSession):
{
tmp="GET "+get+"/CloseSession?SessionID="+ QString::number(SessionID)+" \r\n";
break;
}

Добавьте здесь
qDebug() << socket.state();
qDebug() << socket.errorString () ;
чтобы посмотреть состояние подключения на момент передачи второй команды. В общем надо убедиться что соединение не закрыто на момент второй передачи.

Автор: dasV 6.4.2009, 16:34

То же самое, к сожалению, результат вывода примерно следующий

Первый раз

QAbstractSocket::ConnectedState
"Unknown error"
MSG : Connected State is = 3
//i= socket.write( tmp.toUtf8() ) ;
//socket.flush ();
MSG : Connected State is = 3

Второй раз

QAbstractSocket::ConnectedState
"Unknown error"
MSG : Connected State is = 3
//i= socket.write( tmp.toUtf8() ) ;
//socket.flush ();
MSG : Connected State is = 3



Раскрывающийся текст

qlonglong ssl_class::WriteMsgToSrv()
{
    QString tmp;
    qlonglong i;
    switch(state)
    {
        case(StartSession):
        {
            tmp="GET "+get+"/StartSession?Login="+login+"&Password="+password+"&Gmt=3 \r\n";
            break;
        }

        case(CloseSession):
        {
            tmp="GET "+get+"/CloseSession?SessionID="+ QString::number(SessionID)+" \r\n";
            break;
        }
    }
            qDebug() << socket.state();
            qDebug() << socket.errorString ();

emit displayMessage("MSG : Connected State is = " + QString::number( QAbstractSocket::ConnectedState) );

i= socket.write( tmp.toUtf8() );
socket.flush ();

emit displayMessage("MSG : Connected State is = " + QString::number( QAbstractSocket::ConnectedState) );

return( i );

}



Спасибо.

Автор: Sokoloff 6.4.2009, 18:09

Цитата(dasV @ 6.4.2009, 13:44) *
Добрый день.

Протокол общения обычный http, я знаю, сколько мне передадут или должны передать (так как есть Content-Length: который я обрабатываю) и получаю длину, которую пока не обрабатываю.

Но это все ерунда полная (хотя и интересная), мне важно узнать, по какой причине socket не пишет на сервер второй раз =(

Спасибо.


Сам я с QT только разбираюсь, поэтому кодом помочь не могу, но опыт работы с HTTP есть, может помогут следующие идеи.
HTTP - это протокол без поддержки сессий, т.е. запрос/получение страницы отдельная tcp сессия. Поэтому когда tcp сессия закрылась, значит получили все данные. Темболее, что поле content-length может и не присутьствовать в http заголовке.

Автор: dasV 7.4.2009, 18:36

Похоже, что так оно и есть, после получения данных и повторной попытки записи, не происходит закрытие socket, видимо его принудительно надо закрывать, так как это ssl соединении а работаем мы с http.
Сейчас проверил, что выдает socket.waitForReadyRead(60000) “не пугайтесь это из моего гениального творения, без слотов =)” при попытке повторного чтения, и выяснил что

waitForReadyRead QAbstractSocket::UnconnectedState
waitForReadyRead "Remote host closed"

QString Sms_class::ReadSocket()
{
    out<<"MSG : Open Mode " <<socket.openMode ()<<endl;
    
    if(!socket.waitForReadyRead(60000))
        {
            qDebug() <<"waitForReadyRead"<< socket.state();
            qDebug() <<"waitForReadyRead"<< socket.errorString ();        
            return(0);
        }
    return(socket.readAll());
}


самое интересное что openMode() выдает “MSG : Open Mode 3” то есть у нас все хорошо =)

То есть нам надо будет делать socket.close(); после получения ответа от сервера.

Буду курить носки и много думать, привет анабиоз =)

Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)