Packet getting fragmented when sending over QTcpSocket
I'm trying to write a single class to support XMPP protocol, it's packets are XML nodes.
I'm using QTcpSocket for connection with the server, but sometimes when I get a big packet the readReady signal is emited twice and I get the packet fragmented. What's the best way to bypass this? I know I can have a buffer that I write all incoming data to and process the nodes when they are done, but i this the best and most optimal way? I'm quite new to Qt so it's possible I'm missing something, I'm learning new things every day.
Fragmentation with XMPP is not even half as confuing as fragmentation with a binary protocol. I'm also trying to write a class to support Gadu-Gadu (polish IM protocol) and it's packages are binary - there's always a "header" packet that tells me what type of packet I'm going to get next and what' it's size and then I get the packet, but sometimes it also get's fragmented. I haven't try to bypass this by using a buffer cause it's not easy finding out where one packet ends and another header starts.
Any help appreciated.
Re: Packet getting fragmented when sending over QTcpSocket
Re: Packet getting fragmented when sending over QTcpSocket
Quote:
Originally Posted by
arturo182
I'm using QTcpSocket for connection with the server, but sometimes when I get a big packet the readReady signal is emited twice and I get the packet fragmented. What's the best way to bypass this? I know I can have a buffer that I write all incoming data to and process the nodes when they are done, but i this the best and most optimal way? I'm quite new to Qt so it's possible I'm missing something, I'm learning new things every day.
You can either buffer the data in your application or use QXmlStreamReader for parsing the xml. It can operate on incomplete data - when more data is ready, you can ask it to continue where it left off. There is also a third choice - do nothing (ignore readyRead()) until the whole package of data arrives. If the messages are small enough, they will fit into the internal buffer so you don't have to keep making room for more data.
Quote:
Fragmentation with XMPP is not even half as confuing as fragmentation with a binary protocol.
It's not fragmentation, it's analog world where things don't happen in an instant.
Re: Packet getting fragmented when sending over QTcpSocket
Quote:
a third choice - do nothing (ignore readyRead()) until the whole package of data arrives. If the messages are small enough, they will fit into the internal buffer so you don't have to keep making room for more data.
But this method will freez program, until rest of package will not receive to us, right?
P.S: Sorry for my poor english...
Re: Packet getting fragmented when sending over QTcpSocket
Quote:
Originally Posted by
Kill3rReaper
But this method will freez program, until rest of package will not receive to us, right?
No, why? Socket operations are asynchronous, they don't freeze your gui.
Re: Packet getting fragmented when sending over QTcpSocket
Look at this example:
Code:
<message from="smn@jabber.com"><body>Lorem ipsum... (and a lot of text)</body></message>
If this verse will longer than, for example, 2000 bytes, then this message, will be broken in the, again for example :P, 1500 byte. Rest 500 bytes will be send in new packet. So, I don't know, where my message ends, because between tags <body> and </body> I can send XML code, which can have inside tag </body> or </message> :(
I hope you understand my english. If no, can I write to you pm in polish language? :D
Re: Packet getting fragmented when sending over QTcpSocket
The fact that it comes in parts is meaningless and has nothing to do with freezing anything. If you know what you expect then you can wait until your expectations are filled. Doing this by ignoring the data is probably not the best idea but it is possible. A better way is to read the pending data (thus freeing the incoming buffer), scanning that data for end of message (which is easy in your case) and either processing the data or waiting until more comes in. Remember that you can also get more than one message in a single go, you need to handle situations like that as well.
Re: Packet getting fragmented when sending over QTcpSocket
Ehhhh, I thought there was some other way to do it :(
Anyway, thank you for answer!
Czesc ;)
Re: Packet getting fragmented when sending over QTcpSocket
Quote:
Originally Posted by
Kill3rReaper
Ehhhh, I thought there was some other way to do it
Sure there is. Use QXmlStreamReader.
Re: Packet getting fragmented when sending over QTcpSocket
Ehhh... I just was writing new class for XML packets, when I try to write something XML to <body> </body> section... Code between these tags is interpretting by my algorism... When I was using QDomElement, I did't have got that problem :( What I can do?
Re: Packet getting fragmented when sending over QTcpSocket
and what is the problem exactly?
Re: Packet getting fragmented when sending over QTcpSocket
My english sux very much...
For example:
Code:
<message from='test@jab.com/Jabber' type='chat' xml:lang='pl' to='test@jabbim.pl'><active xmlns='http://jabber.org/protocol/chatstates'/><body>Hey!</body></message>
If I change body section to: "Hej <someth" my application freezes.
Re: Packet getting fragmented when sending over QTcpSocket
Quote:
Originally Posted by
Kill3rReaper
My english sux very much...
If I change body section to: "Hej <someth" my application freezes.
I have not used the XML parser in Qt before, but other XML parsers would interpret the '<' symbol in the body as the opening to a tag. The parser would then read until it finds a closing '<' tag. Try converting the '<' to "<" and see if your program still hangs.
You can do the string conversion manually or for '<' and '>' with QString's replace string functions. There might be a method in one of the XML classes to quote characters that are meaningful to XML for you.
Re: Packet getting fragmented when sending over QTcpSocket
Well, he can't change the packet cause that's the way the server sends it.
My solution would be if you see the opening "body" tag, treat everything that follows as text untill you reach closing "body" tag. But that's not perfect cause someone could be chatting about HTML and send </body> and that would screw the parser up.
Re: Packet getting fragmented when sending over QTcpSocket
Quote:
Originally Posted by
wrdieter
I have not used the XML parser in Qt before, but other XML parsers would interpret the '<' symbol in the body as the opening to a tag. The parser would then read until it finds a closing '<' tag. Try converting the '<' to "<" and see if your program still hangs.
You can do the string conversion manually or for '<' and '>' with QString's replace string functions. There might be a method in one of the XML classes to quote characters that are meaningful to XML for you.
It's good idea :)
I thought about use QDomElement class to solve this problem, but your solution sounds good :)
P.S: I know that the XML parser interprets '<' symbol as the opening tag, but I could not cope with this ;/