В продолжение темы. Я почти в отпаде, говоря честно
Есть не-шибко простая система -
клиент один, рассылает серверам пакеты, сервера - простые guiless, в одном потоке просто ждут, пока придёт чего, хавают данные - и возвращают всё назад и ждут дальше. Идиллия.
Так вот в чём засада. Когда я проектировал и собирал первую версию, была qt4.1.1 - и хорошо было.
Начиная с 4.1.3 - не работет как надо (не проверял 412, может там тоже всё плохо). Засада в том, что или не передаётся от клиента весь запрос в какой-то момент - или не приходит к "серверу" всё. Блин, ну на одной машине когда сидят, как это может не дойти? всякие wautForBytesWritten и flush на клиенте не приводят ни к какому ощутимому результату.
код "сервера" -
#include <iostream>
using namespace std;
#include <QCoreApplication>
#include <QDataStream>
#include<QTcpSocket>
#include <QColor>
#define clamp(x,min,max) (x <= min ? min : (x >= max ? max : x))
typedef float float3[3];
struct bucketDim
{
int w, h;
float dx0, dx1, dy0, dy1;
};
struct geobucket : bucketDim
{
float3* P;
float3* V;
geobucket() {};
geobucket(const bucketDim *src) { *(bucketDim*)this = *src; P = NULL; V = NULL; };
~geobucket() {};
};
struct imgbucket : bucketDim
{
float3* C;
float* a;
imgbucket(const bucketDim *src) { *(bucketDim*)this = *src; C = NULL; a = NULL; };
~imgbucket() { if(C != NULL) delete [] C; if(a != NULL) delete [] a; };
};
enum packetType
{
unknownPacket = 0,
imagePacket,
shaderParameter,
shutdownRenderNode,
packetTypeForce = 0xffffffff
};
geobucket* readGeo(quint32 blockSize, QDataStream&in);
bool flushUnknown(quint32 blockSize, QDataStream&in);
imgbucket* render(geobucket*);
int main(int argc, char *argv[])
{
//QCoreApplication a(argc, argv);
QTcpSocket socket;
socket.connectToHost("localhost", 5005);
if(!socket.waitForConnected())
{
cout << "FAILED CONNECTION" << endl;
};
// HANDSHAKING
{
QDataStream in(&socket);
in.setVersion(QDataStream::Qt_4_0);
quint16 blockSize;
while(socket.bytesAvailable() < (int)sizeof(quint16))
{
if (!socket.waitForReadyRead(5000))
{
cout << "WAIT TIMEOUT" << endl;
return -1;
}
}
in >> blockSize;
while(socket.bytesAvailable() < blockSize)
{
if (!socket.waitForReadyRead(5000))
{
cout << "WAIT TIMEOUT" << endl;
return -1;
}
}
QString info;
in >> info;
QByteArray ba = info.toAscii();
cout << "HANDSHAKE: " << ba.constData() << endl;
// SEND HANDSHAKE
QByteArray block;
QDataStream buff(&block, QIODevice::WriteOnly);
buff.setVersion(QDataStream::Qt_4_0);
buff << (quint16)0;
buff << QString("Bla-Bla");
buff.device()->seek(0);
buff << (quint16)(block.size() - sizeof(quint16));
socket.write(block);
socket.waitForBytesWritten(-1);
cout << "HANDSHAKING SUCCESSFULL" << endl;
}
------- тут всё отлично проходит
// MAIN LOOP
int bc = 0;
QDataStream in(&socket);
in.setVersion(QDataStream::Qt_4_0);
while(true)
{
// READ
quint64 baa; // Bytes Available
while((baa = socket.bytesAvailable()) < 2*sizeof(quint32))
{
if (!socket.waitForReadyRead(-1)) // WAIT AND ALL
{
cout << "WAIT TIMEOUT" << endl;
break;
}
}
quint32 blockSize;
in >> blockSize;
quint32 packet;
in >> packet;
---------------- а вот здесь приключения
----------------один/два раза весь цикл выполняется полностью и хорошо, всё чо надо приходит, но в какой-то момент здесь bytesAvaialble возвращает недостаточное число байт, и в socket перестают поступать данные
если включить не вечное ожидание, а определить интервал - это не помогает, всё равно bytesAvailable показывает недостаток данных.
while((baa = socket.bytesAvailable()) < blockSize)
{
if(!socket.waitForReadyRead(-1))
{
//cout << "WAIT TIMEOUT" << endl;
//break;
}
}
--------самая чушь в том, что если из клиента в socket плюнуть ещё хоть 1 байт, пока "сервер" в таком клинче, то всё сдвинется с мёртвой точки. Но это палиатив, проблема-то появилась в поздних версиях. И в 4.2.tp2 она тоже есть, весьма прискорбно.
geobucket* bucket = NULL;
switch(packet)
{
case imagePacket:
bucket = readGeo(blockSize,in);
break;
case shutdownRenderNode:
{
cout << "TERMINATING EVENT OCCURED!" << endl;
exit(0);
return 0;
}
default:
if(!flushUnknown(blockSize,in)) return NULL;
break;
};
cout << "RECEIVED BUCKET: [" << bucket->dx0 << "," << bucket->dx1 << "]:[" << bucket->dy0 << "," << bucket->dy1 << "] (" << bucket->w << "x" << bucket->h << ")" << endl;
cout << "BLOCKZISE: " << blockSize << endl;
imgbucket* img = render(bucket);
// WRITE
QByteArray block;
QDataStream buff(&block, QIODevice::WriteOnly);
buff.setVersion(QDataStream::Qt_4_0);
// PACKETSIZE
buff << (quint32)0;
// PACKET TYPE
buff << (quint32)imagePacket;
// BUCKET
{
buff << img->dx0 << img->dx1 << img->dy0 << img->dy1 << img->w << img->h;
}
int cnt = img->w*img->h;
// C
{
for(int i=0;i<cnt;i++)
{
buff << img->C
buff << img->C[1];
buff << img->C[2];
}
}
// a
{
for(int i=0;i<cnt;i++) buff << img->a;
}
// SETUP PACKET
buff.device()->seek(0);
blockSize = block.size() - 2*sizeof(quint32);
buff << blockSize;
// SEND
socket.write(block);
socket.flush();
socket.waitForBytesWritten(-1);
cout << "SENT BUCKET: [" << img->dx0 << "," << img->dx1 << "]:[" << img->dy0 << "," << img->dy1 << "] (" << img->w << "x" << img->h << ")" << endl;
cout << "BLOCKZISE: " << blockSize << endl;
}
socket.disconnectFromHost();
socket.waitForDisconnected(3000);
return 0;
}
geobucket* readGeo(quint32 blockSize, QDataStream&in)
{
bucketDim dim;
in >> dim.dx0 >> dim.dx1
>> dim.dy0 >> dim.dy1
>> dim.w >> dim.h;
geobucket* bucket = new geobucket(&dim);
int cnt = bucket->w*bucket->h;
bucket->P = new float3[cnt];
for(int i=0;i<cnt;i++)
{
in >> bucket->P in >> bucket->P[1];
in >> bucket->P[2];
};
bucket->V = new float3[cnt];
for(int i=0;i<cnt;i++)
{
in >> bucket->V in >> bucket->V[1];
in >> bucket->V[2];
};
return bucket;
};
bool flushUnknown(quint32 blockSize, QDataStream&in)
{
unsigned char b;
for(int i=0;i<blockSize;i++) in >> b;
return true;
};
Что посоветуете? Может я где лох картонный?