PDA

View Full Version : QTcpSocket Newbie Question (not all data being received)



Jothay
10th April 2013, 00:07
For the moment, I'm doing all this code in the same app and communicating over localhost (127.0.0.1). The first toWrite line saying hello world and the Port Number works, but my longer file gets truncated at 8192 characters. Its including the length of the thing to write, so I'm not sure what I'm doing wrong. I'm not new to Qt but I am new to this particular process.

The idea here is that a client would send a file (which contains print job data) over the network through the specified port to the server's client where it will receive the data and do stuff with it, like write to a file, assign it to a printer on the server, etc.

Client Sends the data:

void Client::startTransfer() {
QByteArray toWrite;// = QByteArray("Hello, world (Port: " + QByteArray::number(PORTNUMBER) + ")");
//
QFile file("./PrintJobs/exampleprintjob");
if(!file.open(QIODevice::ReadOnly)) {
QMessageBox::information(0, "error", file.errorString());
}
QTextStream in(&file);
QStringList lines;
while(!in.atEnd()) { lines.append(in.readLine()); }
file.close();
QString file2 = "";
foreach(QString line, lines) { file2 += line + "\r\n"; }
toWrite = file2.toLatin1();
//
client.write(toWrite,toWrite.length()); // length = 188,673 characters, 184 KB file size
//
client.flush();
}
Server reads the data:

Server::Server(QObject * parent): QObject(parent) {
connect(&server, SIGNAL(newConnection()), this, SLOT(acceptConnection()));
server.listen(QHostAddress::Any, PORTNUMBER);
}
void Server::acceptConnection() {
client = server.nextPendingConnection();
connect(client, SIGNAL(readyRead()), this, SLOT(startRead()));
}
void Server::startRead() {
QByteArray buffer;
buffer = client->read(client->bytesAvailable());
emit readFromListening(buffer);
client->close();
}

ChrisW67
10th April 2013, 01:38
You are assuming that data written in one write() is transmitted as one lump, and received in one read(). This is almost never the case and certainly not for 182000 bytes. You need to buffer received data until you have received enough to be a full data unit (whatever that means for your protocol) before processing it.

Jothay
11th April 2013, 23:20
Just in case anyone has any pointers, this is what I rewrote to:



void Client::startTransfer()
{
QByteArray toWrite;// = QByteArray("Hello, world (Port: " + QByteArray::number(PORTNUMBER) + ")");
//
QFile file("./PrintJobs/exampleprintjob");
if(!file.open(QIODevice::ReadOnly)) {
QMessageBox::information(0, "error", file.errorString());
}
QTextStream in(&file);
QStringList lines;
while(!in.atEnd()) { lines.append(in.readLine()); }
file.close();
QString file2 = "";
foreach(QString line, lines) { file2 += line + "\r\n"; }
toWrite = file2.toLatin1();
QList<QByteArray> writeArray;
writeArray.append(QByteArray(""));
int charCount = toWrite.length();
int charIndex = 0;int charIndexM = 1;
int writeIndex = 0;
while (charIndex < charCount) {
if (charIndex > 8192 * writeIndex + 1) { writeIndex++; writeArray.append(QByteArray("")); }
writeArray[writeIndex].append(toWrite[charIndex]);
charIndex++;
}
foreach(QByteArray write, writeArray) {
client.write(write,write.length());
while(true) {
bool b = client.waitForBytesWritten();
if (b) {
break;
}
}
}
//
//client.write(toWrite,toWrite.length()); // length = 188,673 characters, 184 KB file size
//
client.flush();
}