PDA

View Full Version : QtcpSocket read behavior



grisson
9th August 2010, 14:06
Hi.
I'm trying to understand the read behavior of QTcpSocket::read(maxSize) function.
i have the following code (on the server):



#include "server.h"
#include <QTcpSocket>
#include <iostream>
server::server()
{
s=new QTcpServer;

}
void server::active(){
s->listen(QHostAddress::Any,5500);
connect(s,SIGNAL(newConnection()),this,SLOT(nc())) ;
}
void server::nc(){

QTcpSocket *so=s->nextPendingConnection();

while(true){
std::cout <<"wait read..."<<std::endl;
so->waitForReadyRead(5000000);
QByteArray a=so->read(1000);
if (a.endsWith("\r\n"))
a.resize(a.length()-2);
if (a.startsWith("quit"))
break;

//just to see readed text, this line will be deleted
std::cout <<a.length()<<"--"<<QString(a).toStdString()<<std::endl;
}
so->disconnectFromHost();
}



and for testing, i use putty to connect in raw mode to the server.
So, if i send with putty these lines:


testline1


the server will output this


wait read...
9--testline1
wait read...
0--
wait read...


analizing the behavior, line 1,2 and 3 are ok, but line 4 is unexpected(or not?)... if i input other lines like:


testline1
testline222222

lastwasempty

note that line 3 is empty

the server output is:


wait read...
9--testline1
wait read...
0--
wait read...
14--testline222222
wait read...
0--
wait read...
0--
wait read...
12--lastwasempty
wait read...
0--
wait read...



like previois example example, i can't understand why lines 4,8 and 14 are present...(obviously same thing for the "wait read" related lines, but this is not important)
some explanations?

grisson
12th August 2010, 22:46
up, other tests, same problem :(

norobro
13th August 2010, 01:00
Your code works fine on my Debian box. I use netcat to connect (nc localhost 5500) and using your input get the following on the console:
wait read...
10--testline1
wait read...
15--testline222222
wait read...
1--
wait read...
13--lastwasempty
wait read...
Try putting in a qDebug() statement to see what you're actually receiving:
QByteArray a=so->read(1000);
qDebug() << a.toHex();
if (a.endsWith("\r\n"))

squidge
13th August 2010, 07:39
Note that you may not receive data in the same size as what was sent. So if you sent "hello\r\n" for example, you might receive "hello" in one read and "\r\n" in another.

Therefore put your debugging before you strip such a sequence and you may find this is happening.

grisson
14th August 2010, 15:18
Try putting in a qDebug() statement to see what you're actually receiving:
line added.

Maybe is exactly this the problem (or maybe it's a putty problem) because i've done 2 tests:
TEST 1:
1) server on a ubuntu based vps piloted via ssh(putty)
2) raw connection with putty to server on port 5500
the lines sended are:


line
and the server print(che std::cout line was deleted):

wait read...
"6c696e65"
wait read...
"0d0a"


TEST 2:
with this test:
1) same as last test
2) another ssh session to vps, and now the connection is done simply by "telnet localhost 5500"

the line sent was the same as last test ("line")

but the result was:

wait read...
"6c696e650d0a"


maybe can be putty that do something strange before send the data?


Note that you may not receive data in the same size as what was sent. So if you sent "hello\r\n" for example, you might receive "hello" in one read and "\r\n" in another.

Therefore put your debugging before you strip such a sequence and you may find this is happening.


ok..but if it's a normal behavior, how cqan i recognize the differences between a blank line sended (which receive only "\r\n") and a non-blank line which receive the data in one read and the \r\n in another?

norobro
14th August 2010, 16:31
You could change your logic a bit:
QByteArray a;
while(true){
so->waitForReadyRead(5000000);
a.append(so->read(1000));
if(a.endsWith("\n")) {
if(a.endsWith("\r\n")) a.chop(2); else a.chop(1);
qDebug() << a ;
a.clear();
}
}