[Qt-interest] QTcpSocket Problem
Anthony Gabrielson
agabrielson1 at comcast.net
Wed Jan 20 04:11:48 CET 2010
On Tuesday, January 19, 2010 9:26 PM, Dan Mills wrote:
> Your while loop is wrong as it assumes that a given packet will not be
> fragmented. It is NOT an error for a read from a socket to come up
> shorter then you were expecting, the rest of the data might be in the
> next packet, what happens if data is available, but when you call read,
> you only get one byte (which is perfectly valid behaviour)?.
Where does QT's read fit in relative to the OSI model? I know my code is
simple - that's actually the point for the time being. Hopefully I'm at
least at the transport layer and I don't have to worry about packets
assuming they are coming in a somewhat regular fashion. Similar code
utilizing UNIX read/write, what I'm quasi porting this from, has run across
fairly large network segments without any issues in the past. I'm really
hoping the Qt implementation of read/write isn't that different from UNIX.
> You need to keep calling read until you have assembled a complete msg,
> decreasing the size and incrementing the source pointer as you go.
Read is populating a structure; if I keep calling it I will have no idea
what is coming in based on how the code is currently structured. I know the
code is a bit simplistic and I would like to make it more robust, I just
want simple to work first before I get overly bogged down and this
convention has worked really well for me in the past. Also depending on
where Qt's read fits in on the OSI model I'm nowhere near the packet. I'm
also not currently having an issue getting to few bytes - I'm either getting
the correct number or 0.
> Why is this reporting the file as phd.pdf, when getfile thinks it is
> file.pdf?
I'm busted I edited the output for brevity and a bit of content :) and I
missed one change...
> Plenty, but without seeing your revised code I am having a crystal ball
> failure.
Here is the one updated function:
int getFile(QTcpSocket &inet_sock)
{
NetMSG msg;
QString filename;
qint64 bytesRead;
//Get the filename
if( (bytesRead = inet_sock.read((char *) &msg, sizeof(msg))) !=
sizeof(msg)){
qDebug() << "getFile: (name) bytes read " << bytesRead << " of " <<
sizeof(msg);
return 1;
}
filename = QString(msg.mbody).trimmed();
qDebug() << "getFile: type " << msg.msize << " size " << msg.mtype;
qDebug() << "getFile: filename " << filename;
QFile file = filename.trimmed();
if(file.open(QFile::WriteOnly) != true){
qDebug() << "getFile: local_file open failed";
return 2;
}
//loop over the file until END_DATA is recv
while(true){
inet_sock.waitForReadyRead(-1);
if( (bytesRead = inet_sock.read((char *) &msg, sizeof(msg))) == 0 ){
qDebug() << "getFile: only read " << bytesRead << " bytes " <<
sizeof(msg);
file.close();
return 3;
}
qDebug() << "getFile: recv " << msg.msize << " Bytes";
switch(msg.mtype){
case DATA:
if(file.write(&(msg.mbody[0]), msg.msize) == -1){
qDebug() << "getFile: local write failed";
return 4;
}
break;
case END_DATA:
file.close();
qDebug() << "getFile: transfer for file " << filename << "
completed " << msg.msize;
return 0;
default:
qDebug() << "getFile: unknown message type " << msg.mtype <<
" claims size of " << msg.msize;
qDebug() << "getFile: this is an unrecoverable error,
goodbye";
file.close();
return 5;
} // end switch
memset(&msg,0,sizeof(msg)); //Catch - set mem to zero
} // end while
return 6; //More of a place holder, shouldn't get here.
}
Thanks,
Anthony
More information about the Qt-interest-old
mailing list