Originally Posted by
jpn
Ok, remember that we know nothing about all the functions you have in myUnit. I was basically tracking where does the execution come from. A slot? An event handler? It might be easier to track the problem if you provide a little bit more information. Could you perhaps attach myunit.h and myunit.cpp?
Hey jpn,
I know that and really appreciate all your care.
As to attaching the code... alas... there are portions of it containing too much proprietary information, which I cannot disclose (protected by NDA).
The app, however, is a simple one:
- A new thread gets fired upon an incoming tcp connection
void Server::incomingConnection ( int socketDescriptor )
{
nbrClients++;
myUnit *tunit = new myUnit ( socketDescriptor,this );
connect ( tunit, SIGNAL ( finished() ), tunit, SLOT ( deleteLater() ) );
tunit->start();
return;
}
void Server::incomingConnection ( int socketDescriptor )
{
nbrClients++;
myUnit *tunit = new myUnit ( socketDescriptor,this );
connect ( tunit, SIGNAL ( finished() ), tunit, SLOT ( deleteLater() ) );
tunit->start();
return;
}
To copy to clipboard, switch view to plain text mode
- I link signals and slots like this (in myUnit::myUnit):
// link socket signals to this thread's slots.
connect ( &tcpSocket, SIGNAL ( readyRead() ), this, SLOT ( incomingData() ) );
connect ( &tcpSocket, SIGNAL ( disconnected() ), this, SLOT ( disconnected() ) );
// link socket signals to this thread's slots.
connect ( &tcpSocket, SIGNAL ( readyRead() ), this, SLOT ( incomingData() ) );
connect ( &tcpSocket, SIGNAL ( disconnected() ), this, SLOT ( disconnected() ) );
To copy to clipboard, switch view to plain text mode
- this is my incomingData() :
void myUnit::incomingData ()
{
short zerocount=0; // number of zero header values to check.
quint16 dataLength=0;
unsigned int totalBytes = 0; // quick sanity check...
totalBytes = tcpSocket.bytesAvailable();
if ( totalBytes < 4 ) return; // bogus tx...
while ( zerocount < 4 && dataLength==0 )
{
inData >> dataLength;
if ( dataLength==0 ) zerocount++;
}
// sanity checks...
// exceed number of tries... bogus tx. return.
if ( zerocount>3 )
{
cout << "WAY TOO MUCH ZEROES!" << endl;
return;
}
// we wont have packets bigger than this. so it's a bogus tx.
if ( dataLength == 0xFFFF || dataLength==0 )
{
cout << "DATA LENGTH MISMATCH! [" << dataLength <<"]" << endl;
return;
}
// wait for a maximum of 5 secs for data...
if (tcpSocket.bytesAvailable() < dataLength)
{
tcpSocket.waitForReadyRead ( 5000 );
}
// if 5 secs *still* not enough get out of here!
if (tcpSocket.bytesAvailable() < dataLength) {
this->disconnected();
return;
}
avlData=tcpSocket.readAll();
if ( !gotImei )
{
checkImei ( avlData );
}
else
{
parseData ( avlData );
}
return;
}
void myUnit::incomingData ()
{
QString dt = getDateTime();
short zerocount=0; // number of zero header values to check.
quint16 dataLength=0;
unsigned int totalBytes = 0; // quick sanity check...
totalBytes = tcpSocket.bytesAvailable();
if ( totalBytes < 4 ) return; // bogus tx...
QDataStream inData ( &tcpSocket );
while ( zerocount < 4 && dataLength==0 )
{
inData >> dataLength;
if ( dataLength==0 ) zerocount++;
}
// sanity checks...
// exceed number of tries... bogus tx. return.
if ( zerocount>3 )
{
cout << "WAY TOO MUCH ZEROES!" << endl;
return;
}
// we wont have packets bigger than this. so it's a bogus tx.
if ( dataLength == 0xFFFF || dataLength==0 )
{
cout << "DATA LENGTH MISMATCH! [" << dataLength <<"]" << endl;
return;
}
// wait for a maximum of 5 secs for data...
if (tcpSocket.bytesAvailable() < dataLength)
{
tcpSocket.waitForReadyRead ( 5000 );
}
// if 5 secs *still* not enough get out of here!
if (tcpSocket.bytesAvailable() < dataLength) {
this->disconnected();
return;
}
QByteArray avlData;
avlData=tcpSocket.readAll();
if ( !gotImei )
{
checkImei ( avlData );
}
else
{
parseData ( avlData );
}
return;
}
To copy to clipboard, switch view to plain text mode
- This is my disconnected() :
void myUnit::disconnected()
{
server->nbrClients--;
textcolor ( BRIGHT, YELLOW, BLACK );
cout << qPrintable(dt) << ": Unit [" << imei.data() << "] disconnected." << " active clients: " << server->nbrClients << endl;
textcolor ( BRIGHT, WHITE, BLACK );
this->quit();
return;
}
void myUnit::disconnected()
{
QString dt = getDateTime();
server->nbrClients--;
textcolor ( BRIGHT, YELLOW, BLACK );
cout << qPrintable(dt) << ": Unit [" << imei.data() << "] disconnected." << " active clients: " << server->nbrClients << endl;
textcolor ( BRIGHT, WHITE, BLACK );
this->quit();
return;
}
To copy to clipboard, switch view to plain text mode
- Upon getting data (using QDataStream), the app simply parses the records contained therein in a loop that calls updateUnitRecord (db use here) and updateUnitHistory (another db use here)
- After all is done (unit disconnects) the disconnected() fires up and I take care of closing the DB in
myUnit::~myUnit()
{
this->myDB.close();
}
myUnit::~myUnit()
{
this->myDB.close();
}
To copy to clipboard, switch view to plain text mode
Again, thanks for taking a look at it.
Regards,
Pedro.
Bookmarks