PDA

View Full Version : QTcpSocket writing reading problem



Misenko
13th October 2008, 22:35
Hi all

I have two network applications, something like client and server.
On the server side I write data to socket which is in QByteArray.



qint64 size = socket->write(array);
qDebug() << "written" << size;


On the client side in slot which is connected to readyRead signal I first read quint32 which is size of data and then I read data to QByteArray.



QDataStream socketStream(socket);

quint32 size;
socketStream >> size;
qDebug() << "size" << size;
qDebug() << "socketAvailable" << quint32(socket->bytesAvailable());

if (quint32(socket->bytesAvailable()) < size)
return;

QByteArray array = socket->read(size);


So qDebug() on server side give me



warning: written 17980
warning: written 224
warning: written 135176


but on teh client side



warning: size 17976
warning: socketAvailable 17976

warning: size 220
warning: socketAvailable 220

warning: size 135172
warning: socketAvailable 98300


First four warnings are correct becouse I read size which is 4 bytes so it is smaller but the last two do not match. Every time I write to socket more then 98304 bytes it doesnt let me to read them all and I do not know why. In the second calling of client slot when is readyRead emit again there are all data available but I cant read it exactly becouse I have already read their size before. How can I solve this problem? Thanks.

mummy
13th October 2008, 23:15
Look for http://doc.trolltech.com/4.4/qabstractsocket.html#readBufferSize on client side and http://doc.trolltech.com/4.4/qabstractsocket.html#flush on server side.

caduel
14th October 2008, 07:03
i) you have to make sure that enough data is available before reading your block size, too
ii) you have to store the size you read (in some member variable)
iii) you have to check whether you already have the block size, if not: see i); else wait for "block size bytes available *without* reading a blocksize again"

HTH

Misenko
14th October 2008, 21:54
Thanks for responding.

to caduel:
How can I make sure that enough data is available before reading block size?

The problem is that I have connected readyRead signal from socket to slot which take that socket and create new thread to read data from it. So I cant make member variable which will be size becouse when next readyRead is emited with rest of data next thread is created. Isnt there any way how can I wait in thread for rest of data or how can I set how much data must be written for emiting readyRead? I cant use socket->waitForReadyRead(xyz) in thread becouse I do not know how long to wait becouse sometime for one piece of data which I write on server side 2 or 3 or more times readyRead is emited.

caduel
15th October 2008, 07:27
try a method/class like (untested)


class InputProcessor : public QObject
{
Q_OBJECT

QIODevice *input_;
qint64 blocksize_;
QDataStream datastream_;

public:
InputProcessor(QIODevice *input, QObject *parent=0)
: QObject(parent)
, blocksize_(0)
, input_(input)
, datastream(input)
{
connect(input_, SIGNAL(readyRead()), SLOT(slotProcessInput()));
}

public slots:
// connect tcp socket readyRead() here
void slotProcessInput()
{
// if we do not have a block size, wait for enough bytes
if (blocksize_==0)
{ // wait for blocksize
if (input_->bytesAvailable() < sizeof(qint64))
return;
datastream_ >> blocksize_;
}

// now we know the size of the transmitted block: wait for the data
if (input_->bytesAvailable() < blocksize_)
return; // we will be called again

// all data here, read block:
// datastream_ >> ...;

blocksize_ = 0; // wait for next block (size)
}

};


(I have not tried to compile that. Please post if it is buggy.)

HTH