Russian Qt Forum
Ноябрь 23, 2024, 08:40 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2 3   Вниз
  Печать  
Автор Тема: QTcpSocket и QXmlStreamWriter  (Прочитано 23148 раз)
max1983
Гость
« : Июль 21, 2009, 22:06 »

Вот такой кусок кода для записи XML в сокет
Код:
QTcpSocket * Sok = new QTcpSocket();
Sok->connectToHost("127.0.0.1",5000);
 
    QXmlStreamWriter *  wr = new QXmlStreamWriter(Sok);
   
      wr->writeStartElement("RootValue");//
   
wr->writeStartElement("Element_Value0");
wr->writeEndElement();

wr->writeStartElement("Element_Value1");
wr->writeEndElement();

wr->writeStartElement("Element_Value2");
wr->writeEndElement();

wr->writeEndElement();

если пишу
Цитировать
Sok->close();
То данные успешно получает сервер.
но сокет увы закрыт а мне с него еще прочитать данные надо

если пишу
Цитировать
Sok->flush();
то на другом конце ерор "не видит начального элемента" или их больше одного проверить нет как.

ну и что сделать чтоб данные с сокета отправились а сокет не закрылся?
у самого QXmlStreamWriter вроде функций таких нема но лучше перепроверите сами, так как я ламо еще тот. Смеющийся

так как QXmlStreamWriter прибамбас новый(This class was introduced in Qt 4.3.) самплесов в сети по этому поводу просто нет.

Записан
ритт
Гость
« Ответ #1 : Июль 21, 2009, 22:25 »

да уж, в преддверии 4.6 версия 4.3 ещё довольно свежая...

Прямо в начале секции Detailed Description официальной документации по классу QXmlStreamWriter приведён пример:

Код:
     QXmlStreamWriter stream(&output);
     stream.setAutoFormatting(true);
     stream.writeStartDocument();
     ...
     stream.writeStartElement("bookmark");
     stream.writeAttribute("href", "http://www.qtsoftware.com/");
     stream.writeTextElement("title", "Qt Home");
     stream.writeEndElement(); // bookmark
     ...
     stream.writeEndDocument();
« Последнее редактирование: Июль 22, 2009, 01:22 от pastor » Записан
max1983
Гость
« Ответ #2 : Июль 22, 2009, 00:13 »

Конструктивный ответ:
Да, этот пример я не обнаружил(Detailed Description )
Да ета фишка мне не помогла так как совсем не похожа на то что мне надо.
И мой код не отличается от приведенного!
Если ты про дополнительные теги вроде writeStartDocument и setAutoFormatting что сними что без них разницы нет.
Да ты не побывал писать в поток сокета XML иначе понял мою проблему.


« Последнее редактирование: Июль 22, 2009, 01:35 от max1983 » Записан
Blayder
Гость
« Ответ #3 : Июль 22, 2009, 00:32 »

Цитировать
void QXmlStreamWriter::writeStartDocument ( const QString & version )

Writes a document start with the XML version number version.

See also writeEndDocument().
Цитировать
void QXmlStreamWriter::writeEndDocument ()

Closes all remaining open start elements and writes a newline.

See also writeStartDocument().

http://doc.trolltech.com/4.5/qxmlstreamwriter.html#writeEndDocument

Может быть он на это тебе намекал... то, чего в твоем коде нету?
Я сам этого не пробовал да и тоже новичек...
Но наскоко я считаю, ваша проблема кроется в том, что вы не завершаете запись документа в стриме... собсна оттуда и ноги проблемы...
« Последнее редактирование: Июль 22, 2009, 01:23 от pastor » Записан
f-r-o-s-t
Гость
« Ответ #4 : Июль 22, 2009, 01:13 »

В примере быстрее код записи в файл а не в сокет. Спорим?

Ну допустим в файл, что это меняет ?
« Последнее редактирование: Июль 22, 2009, 01:25 от pastor » Записан
max1983
Гость
« Ответ #5 : Июль 22, 2009, 01:28 »


Цитировать
что это меняет ?

А как ты думаешь?
Я думаю что: ты думаешь что ничего это не меняет.
Я также полагаю: ты знаешь что по етому поводу думаю я, а точнее я думаю что ето все меняет и пример мне не годится.
Ну раз ты все равно спросил значит ты хочешь доказательств или здравых аргументов.
Воспользуйся своим советом
Цитировать
прочитать внимательно
Нет ты не подумай совет просто отличный!
У меня например 2 книги на руском по QT и 2 на Eng и там нет примеров по QXmlStreamWriter.
Видишь я сам следую этому правилу.

кроче.. просто не работает.
Я не отрицаю что мне не хватает знаний в QT Шокированный
Записан
max1983
Гость
« Ответ #6 : Июль 22, 2009, 01:44 »

Ладно давай еще раз, тебе нужно что бы сокет не закрылся, а данные отправились ?

Ага.
Местный Священник замял все прикольные фразы в топике.
И я вроде как нашел решение проблемы.
Пока говорить рано но всегда интересно знать что думают остальные лысые с тату.
мнение ежиков интересует меньше.
Я все образно никого не оскорбляю...
Записан
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #7 : Июль 22, 2009, 02:02 »

И я вроде как нашел решение проблемы.

И что за решение?
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
max1983
Гость
« Ответ #8 : Июль 22, 2009, 02:04 »

Цитировать
И что за решение?
Обязательно отпишусь как буду уверен.
Записан
ритт
Гость
« Ответ #9 : Июль 22, 2009, 12:48 »

заглянул в сорцы - writeStartDocument / writeEndDocument нужны для записи well-formed xml
и, исходя из твоей тарабарщины:
Цитировать
если пишу
Цитировать
Sok->flush();
то на другом конце ерор "не видит начального элемента" или их больше одного проверить нет как.
сниппет должен завершаться так:
Код:
     stream.writeEndDocument();

     output.flush();
Записан
max1983
Гость
« Ответ #10 : Июль 22, 2009, 15:35 »

Цитировать
и, исходя из твоей тарабарщины:
О! Ты еще кода моего не видел  Смеющийся вот там то точно разобраться не просто.
Но специально для тебя я облегчил его восприятие и показываю как не работает.
Код:

    QTcpSocket * Sok = new QTcpSocket();
    Sok->connectToHost("127.0.0.1",5000);
 
    QXmlStreamWriter *  wr = new QXmlStreamWriter(Sok);
    QXmlStreamReader * rd = new QXmlStreamReader(Sok);
   
   

   
    wr->setAutoFormatting(true);
    wr->writeStartDocument();
    wr->writeStartElement("ValueStart");//Root
   
wr->writeStartElement("ValueNext");
wr->writeEndElement();

wr->writeStartElement("ValueNext2");
wr->writeEndElement();

wr->writeStartElement("ValueNext3");
wr->writeEndElement();

wr->writeEndElement();
wr->writeEndDocument();//End Root
Sok->flush();


И при подобном подходе вылазит ошибка на другом конце провода.
как я и писал.
Но если заменить flush на close ошибки нет.
Ну раз ты даже сырцы всковернул ты явно не думаешь что моя тарабарщина без смысла.
Или хочешь что-то доказать.

так как обещал показать как оно должно работать привожу кусок кода который работает на 16,66666666666667%
Почему цифра такая загадочная путь ответить ежик.
Код:
   QTcpSocket * Sok = new QTcpSocket();
    Sok->connectToHost("127.0.0.1",5000);
 
   wr = new QXmlStreamWriter(Sok);
   rd = new QXmlStreamReader(Sok);
   connect(Sok, SIGNAL(readyRead()),this, SLOT(IncomingDataXML()));

  wr->writeStartElement("ValueStart");//Root
   
wr->writeStartElement("ValueNext");
wr->writeEndElement();

wr->writeStartElement("ValueNext2");
wr->writeEndElement();

wr->writeStartElement("ValueNext3");
wr->writeEndElement();

wr->writeEndElement();


Все кто хочет юзать такие фишки(QXmlStreamWriter & QXmlStreamReader) учтите что считывание происходит калбаком в слот
а запись как пожелаете, видать сокеты не асинхронные.

Если найду что добавить обязательно добавлю в етот топ.
Записан
BigZ
Гость
« Ответ #11 : Июль 22, 2009, 16:22 »

А на функцию IncomingDataXML можно взглянуть?
Записан
max1983
Гость
« Ответ #12 : Июль 22, 2009, 16:33 »

А на функцию IncomingDataXML можно взглянуть?
Хотя я ее еще не закончил.. чтож щедрости моей нет предела
Код:
void MainWindowImpl::IncomingDataXML()
{



while(!rd->atEnd())
{

rd->readNext();

textEdit->append(rd->tokenString());

switch(rd->tokenType())
{


case QXmlStreamReader::NoToken:
{

}
break;

case QXmlStreamReader::Invalid:
{

}
break;

case QXmlStreamReader::StartDocument:
{

}
break;

case QXmlStreamReader::EndDocument:
{

}
break;

case QXmlStreamReader::StartElement:
{
textEdit->append("Name: "+  rd->name().toString() + " Value: " + rd->readElementText());
}
break;

case QXmlStreamReader::EndElement:
{


}
break;

case QXmlStreamReader::Characters:
{

}
break;

case QXmlStreamReader::Comment:
{

}
break;

case QXmlStreamReader::DTD:
{

}
break;

case QXmlStreamReader::EntityReference:
{

}
break;

case QXmlStreamReader::ProcessingInstruction:
{

}
break;




}




}

}

кстати если кто здесь видит не правильный подход
и у него есть идеи почему 1 раз из 6 запросов данные приходя без проблем а а остальные
разы ошибка у rd->atEnd() ---------->>>> QXmlStreamReader::UnexpectedElementError
Принимаются любые даже безумные идеи.
Да! Размер входящего XML 60 кб он не меняется и другой клиент написанный на .Net всегда принимал без проблем.
« Последнее редактирование: Июль 22, 2009, 16:39 от max1983 » Записан
BigZ
Гость
« Ответ #13 : Июль 22, 2009, 16:50 »

When atEnd() and hasError() return true and error() returns PrematureEndOfDocumentError, it means the XML has been well-formed so far, but a complete XML document has not been parsed. The next chunk of XML can be added with addData(), if the XML is being read from a QByteArray, or by waiting for more data to arrive if the XML is being read from a QIODevice. Either way, atEnd() will return false once more adata is available.


Ты уверен, что у тебя ошибка UnexpectedElementError а не PrematureEndOfDocumentError?
Судя по твоей проблеме у тебя именно PrematureEndOfDocumentError, а это говорит о том что данных доступных для чтения не достаточно для завершени XML конструкции. В этом случае выходи из
IncomingDataXML, на след. заходе дочитаешь оставшиеся.
Записан
max1983
Гость
« Ответ #14 : Июль 22, 2009, 19:20 »

Ты уверен, что у тебя ошибка UnexpectedElementError а не PrematureEndOfDocumentError?
Судя по твоей проблеме у тебя именно PrematureEndOfDocumentError, а это говорит о том что данных доступных для чтения не достаточно для завершени XML конструкции. В этом случае выходи из IncomingDataXML, на след. заходе дочитаешь оставшиеся.

Клевые идеи! Прям как по заказу...
Тем не менее я решил их проверить.
Сначала ты предположил что я не правильно диагностировал ошибку а потом ты сделал вид что я с етим согласился.
И так ты утверждаемый что данных слишком много чтоб за раз их можно было принять.
Значит увеличим буфер приема в сокете.
Сначала я сделал так
Цитировать
Sok->setReadBufferSize(165536);
эт не помогло.
Данные обрывались в самом начале(как и было до етого)
и текстовый бокс гласил
Цитировать
StartDocument
StartElement
Name: GAME Value:

тогда я увеличил до 111165536 -не знаю сколько ето но много!
Не помогло!

тогда решил уменьшать
и только кода поставил 20
картина хоть как-то изменилась
пришло
Цитировать
StartDocument
Invalid
StartElement
Name: GAME Value:
StartElement
Name:  Value: 1485

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

уменьшил объем данных до 5 кб
эт не помогло.

Цитировать
на след. заходе дочитаешь оставшиеся.

эт ты се как представляеш ?
у меня же QXmlStreamReader !
а если у меня несколько вложенных циклов которые что-то инициализируют.
Притом раз в 6-9 раз данные приходят нормально - разом.
Пнятно что ничего не понятно.
Ошибку определяю так
Цитировать
int z=0;

   
   while(!rd->atEnd() || (z = rd->atEnd()))
   {
      int i = rd->atEnd();
   
      
      QMessageBox::about(0,"AAAAAAAAAAAA",QString::number(z));
      

то есть циферка 1 говорит что ошибка UnexpectedElementError

Ну а на запрос
Цитировать
QMessageBox::about(0,"AAAAAAAAAAAA",rd->errorString());
вернулась фраза
Цитировать
Expected character data

Есть идеи?
Записан
Страниц: [1] 2 3   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.057 секунд. Запросов: 22.