How to read all data from QTcpSocket
-
Hi guys!
I have a question for you about sockets. How I can read all data from QTcpSocket. I can't understand how to read all packages and create QByteArray with all data which I get by socket. I have added code to my class:
@
recivedData.append(client->readAll());if(client->atEnd()) { qDebug()<<"DATAS: "<<recivedData; QImage img = QImage::fromData(recivedData, "PNG"); recivedData = ""; }
@
But the method client->atEnd() is calling every time when I read client data. As I understand this method is show length of current packages. How I can get a length of data.
P.S. I send data from iOS application by socket. And in start send data I send the length of data like 4 bytes. How I can read this data. The code on Objective-C for send data to socket looks like:
@
NSString* s = @"#";
NSMutableData* d = [[NSMutableData alloc] initWithData:[[data base64Encoding] dataUsingEncoding:NSUTF8StringEncoding]]; //Get a data to send to the socket server (in my case it's image.) Also I'm converting image binary data to Base64 hash.[d appendData:[s dataUsingEncoding:NSUTF8StringEncoding]]; //This I try added a symbol for detect of end data. I can't get it in Qt application.
uint len = [d length]; //Take a full length of data.
[mOutputStream write:(void *)&len maxLength:sizeof(uint)]; //Send length of data to socket.
NSInteger bytes = [mOutputStream write:[d bytes] maxLength:len]; //Send data to socket.
@I can't understand how to append all data in one packages. Help me please? Thanks for any help.
-
Well, you are receiving data from a TCP connection which is a stream. As long as the connection is established, there is no way of knowing when you really reach the end of the stream.
At any point in time, more data can come. When you call @client->atEnd()@ you get true because at that point in time, there is no more data available for this connection, but it does not mean that more data will not be available soon.
When you want to transmit data over a TCP connection, you can use different approaches:
Open the connection, transfer all the data and close the connection: that way when you get the connection close event, it means everything was transmitted. However if you want to transfer multiple buffers, you will have to reopen a connection for each which can be quite time and resources consuming.
Another neater solution is to first write the total amount of data you want to write to the connection, and then read that exact amount of data. You can google for TLV (Type Length Value) to find out more about such techniques. -
[quote author="rcari" date="1354618410"]Well, you are receiving data from a TCP connection which is a stream. As long as the connection is established, there is no way of knowing when you really reach the end of the stream.
At any point in time, more data can come. When you call @client->atEnd()@ you get true because at that point in time, there is no more data available for this connection, but it does not mean that more data will not be available soon.
When you want to transmit data over a TCP connection, you can use different approaches:
Open the connection, transfer all the data and close the connection: that way when you get the connection close event, it means everything was transmitted. However if you want to transfer multiple buffers, you will have to reopen a connection for each which can be quite time and resources consuming.
Another neater solution is to first write the total amount of data you want to write to the connection, and then read that exact amount of data. You can google for TLV (Type Length Value) to find out more about such techniques.[/quote]Thanks for the reply! I will try to checking all approaches which you wrote.