Russian Qt Forum

Qt => XML => Тема начата: Fregloin от Август 08, 2011, 08:55



Название: Передача XML по сети
Отправлено: Fregloin от Август 08, 2011, 08:55
Как можно динамически формировать XML и передавать/принимать их по сети?
Желательно без QDataStream, так как клиент написан на Qt, а сервер на чистом Си под лины.
Задача, сформировать небольшой xml документ, отправить на сервер, сервер возвратит тоже небольшой xml док, после чего идёт обмен бинарными данными.


Название: Re: Передача XML по сети
Отправлено: Странник от Август 08, 2011, 15:05
способов вагон. я предпочитаю использовать QXmlStreamWriter. можно сначала сформировать документ в QByteArray-буфер и затем отправить его целиком через QTcpSocket, а можно сразу в QTcpSocket писать. подробности в документации на QXmlStreamWriter.


Название: Re: Передача XML по сети
Отправлено: BigHom от Ноябрь 06, 2012, 08:58
А как принимать xml-документ , как понять , что целиком принят документ , что больше не будет продолжения передачи? Так как приняв часть, обрабатывается только принятая часть, а послав продолжение , то так как нет началА XML-документа , то продолжение как xml-документ не воспринимается?!

Возможно же, передача по частям xml-документа , f не обязательно целиком?!


Название: Re: Передача XML по сети
Отправлено: Bepec от Ноябрь 06, 2012, 10:21
xml - теговый. Если пришёл тег конца, значит передача xml закончена. Вроде всё просто.


Название: Re: Передача XML по сети
Отправлено: BigHom от Ноябрь 06, 2012, 10:26
пришёл файл по сети - даю на обработкку sax-анализатору, всё работает , идёт по веткам, но не доходит до тэга конца, так как ещё не поступил. Потом по сети приходит 2-й кусок - даю на обработку - но продолжение не воспринимается как xml-документ , так как нет тэга начала.
То есть получается , что sax-анализатору можно давать только целиковый xml-документ? Как продолжить обработку с прерванного места , есть ли возможность?


Название: Re: Передача XML по сети
Отправлено: Sancho_s_rancho от Ноябрь 06, 2012, 10:51
Не придумывайте трудностей. Шлите небольшие xml.


Название: Re: Передача XML по сети
Отправлено: Patrin Andrey от Ноябрь 06, 2012, 11:50
А небольшие это сколько? Кто даст гарантию, что "небольшой" не прилитит "маленькими" частями?


Название: Re: Передача XML по сети
Отправлено: mutineer от Ноябрь 06, 2012, 11:58
А небольшие это сколько? Кто даст гарантию, что "небольшой" не прилитит "маленькими" частями?

Передать перед документом его размер и не отдавать документ парсеру, пока он весь не придет


Название: Re: Передача XML по сети
Отправлено: Bepec от Ноябрь 06, 2012, 12:02
Зачем такие сложности? Принимать данные до тех пор, пока не примется завершающий тег xml. После отдаёшь парсеру и врубливаешь бинарные данные куда угодно.


Название: Re: Передача XML по сети
Отправлено: mutineer от Ноябрь 06, 2012, 12:03
То есть понять какой тег завершающий и дождаться его, это проще, чем тупо считать размер полученных данных?


Название: Re: Передача XML по сети
Отправлено: Patrin Andrey от Ноябрь 06, 2012, 12:10
А небольшие это сколько? Кто даст гарантию, что "небольшой" не прилитит "маленькими" частями?

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


Название: Re: Передача XML по сети
Отправлено: Bepec от Ноябрь 06, 2012, 12:20
Помоему да, проще. Особенно с учётом того, что xml формируется им же.

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



Название: Re: Передача XML по сети
Отправлено: Sancho_s_rancho от Ноябрь 06, 2012, 15:33
1. Контролировать, что пришли все байтики должен протокол прикладного уровня(в простейшем случае сочините заголовок фиксированной длины в котором хранится инфа о размере xml данных). Причем это делать обязательно независимо от того, сколько байт или терабайт передается и что пересылается(xml или картинка с голой тетёй). Проще взять TCP, там уже есть гарантия доставки и отбрасывание повторяющихся пакетов. Если очень хочется, то можно хоть хеш каждого xml файла считать.
2. Небольшой размер xml я рекомендовал вместо загадочного частичного парсинга.


Название: Re: Передача XML по сети
Отправлено: mutineer от Ноябрь 06, 2012, 16:21
2. Небольшой размер xml я рекомендовал вместо загадочного частичного парсинга.

И какого размера должен быть этот xml, чтобы он гарантировано пришел одним куском?


Название: Re: Передача XML по сети
Отправлено: Sancho_s_rancho от Ноябрь 07, 2012, 08:56
2. Небольшой размер xml я рекомендовал вместо загадочного частичного парсинга.

И какого размера должен быть этот xml, чтобы он гарантировано пришел одним куском?
Я не знаю термина "один кусок". UDP пакет - это кусок? Так вот,  датаграмма для udp ТЕОРЕТИЧЕСКИ может достигать 65535 вычесть длину заголовка. Все зависит от сетевого стека ОС. На практике не один человек в здравом рассудке на это полагаться не будет.
Вот что пишут Qt-шники
Datagrams are always written as one block. The maximum size of a datagram is highly platform-dependent, but can be as low as 8192 bytes. If the datagram is too large, this function will return -1 and error() will return DatagramTooLargeError.

Sending datagrams larger than 512 bytes is in general disadvised, as even if they are sent successfully, they are likely to be fragmented by the IP layer before arriving at their final destination.


Название: Re: Передача XML по сети
Отправлено: Sancho_s_rancho от Ноябрь 07, 2012, 08:59
А небольшие это сколько? Кто даст гарантию, что "небольшой" не прилитит "маленькими" частями?
Никто не даст. Скорее ввсего и небольшой прилетит частями. Просто небольшой прилетит быстрее :)


Название: Re: Передача XML по сети
Отправлено: Serr500 от Ноябрь 07, 2012, 09:23
И какого размера должен быть этот xml, чтобы он гарантировано пришел одним куском?
1 байт (это не шутка!)


Название: Re: Передача XML по сети
Отправлено: mutineer от Ноябрь 07, 2012, 11:09
А небольшие это сколько? Кто даст гарантию, что "небольшой" не прилитит "маленькими" частями?
Никто не даст. Скорее ввсего и небольшой прилетит частями. Просто небольшой прилетит быстрее :)

Ну и в чем смысл отправлять "небольшой" xml, если все равно не гарантировано что он придет сразу весь? В чем смысл этого улучшения? Увеличить вероятность правильной работы?


Название: Re: Передача XML по сети
Отправлено: Странник от Февраль 15, 2013, 15:28
А как принимать xml-документ , как понять , что целиком принят документ , что больше не будет продолжения передачи? Так как приняв часть, обрабатывается только принятая часть, а послав продолжение , то так как нет началА XML-документа , то продолжение как xml-документ не воспринимается?!

Возможно же, передача по частям xml-документа , f не обязательно целиком?!
поскольку для передачи я рекомендовал использовать QXmlStreamWriter, для чтения подразумевалось использовать QXmlStreamReader, поддерживающий инкрементальный парсинг. вот выдержка из документации, поясняющая модель использования:
Цитировать
QXmlStreamReader is an incremental parser. It can handle the case where the document can't be parsed all at once because it arrives in chunks (e.g. from multiple files, or over a network connection). When the reader runs out of data before the complete document has been parsed, it reports a PrematureEndOfDocumentError. When more data arrives, either because of a call to addData() or because more data is available through the network device(), the reader recovers from the PrematureEndOfDocumentError error and continues parsing the new data with the next call to readNext().

For example, if your application reads data from the network using a network access manager, you would issue a network request to the manager and receive a network reply in return. Since a QNetworkReply is a QIODevice, you connect its readyRead() signal to a custom slot, e.g. slotReadyRead() in the code snippet shown in the discussion for QNetworkAccessManager. In this slot, you read all available data with readAll() and pass it to the XML stream reader using addData(). Then you call your custom parsing function that reads the XML events from the reader.
связкой пользуюсь давно и в целом успешно. натыкался на какие-то мелкие грабли, но уже и не вспомню.