[Qt-interest] QTcpSocket Problem

Jason H scorp1us at yahoo.com
Wed Jan 20 04:50:48 CET 2010


I didn't read the source, but the 37k issue is very familiar to me.
It sounds like you are expecting continual reads/blocking read from the device. This is hardly the case. The IO buffers seem to be 32k, but there is the interplay of nagel's algorithm I am pretty sure you should just collect data when you get readyRead() signal whose slot is 

readyReadSlot()
{
       if (!outputFile.isOpen())
       outputFile.open(QIODevice::readOnly);
    outputFile.write(socket->readAll());
    if buffer.length()==fileSize)
    {
        outputFile.close();
    }

}

with (int) fileSize and (QFile) outputFile, (QTcpSocket) socket being previously initialized.

This function will  accumipate bytes in the file and close the file when done. The socket will stay open. Just connect it to the readyReadSignal




----- Original Message ----
From: Anthony Gabrielson <agabrielson1 at comcast.net>
To: Dan Mills <dmills at exponent.myzen.co.uk>
Cc: qt-interest at trolltech.com
Sent: Tue, January 19, 2010 10:11:48 PM
Subject: Re: [Qt-interest] QTcpSocket Problem


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

_______________________________________________
Qt-interest mailing list
Qt-interest at trolltech.com
http://lists.trolltech.com/mailman/listinfo/qt-interest



      




More information about the Qt-interest-old mailing list