Whats the live cycle of a connection with QTcpSocket?
My client connects to the application which is listening, here is the client connection code:
setSocketOption(QAbstractSocket::LowDelayOption, 1);
//Get the I/P address
QList<QHostAddress> lstAddresses = QNetworkInterface::allAddresses();
QString strIP;
for( int i=0; i<lstAddresses.size(); i++ ) {
if ( lstAddresses[i] != QHostAddress::LocalHost
&& lstAddresses[i].toIPv4Address() ) {
strIP = lstAddresses[i].toString();
break;
}
}
if ( strIP.isEmpty() == true ) {
strIP = QHostAddress(QHostAddress::LocalHost).toString();
}
//Connect to the Application
qdbg() << "Connecting to: " << strIP << ":" << muint16XMLMPAMport;
connectToHost(strIP, muint16XMLMPAMport);
The port is 8124. This does connect to the server and sends a message with:
void clsSocketClient::sendJSON(const QJsonObject& crobjJSON) {
if ( isOpen() != true ) {
return;
}
//Associate this TCP socket with the output data stream
QByteArray arybytMsg;
QDataStream dsOut(&arybytMsg, QIODevice::WriteOnly);
dsOut.setVersion(clsJSON::mscintQtVersion);
//Send message to data stream
dsOut << QJsonDocument(crobjJSON).toJson(QJsonDocument::Compact);
//Write message
#if defined(DEBUG_SOCKETS)
qint64 int64Written =
#endif
write(arybytMsg);
#if defined(DEBUG_SOCKETS)
QJsonDocument objDoc(crobjJSON);
qdbg() << "clsSocketClient::sendJSON"
<< "[" << int64Written << "]:"
<< QString(objDoc.toJson(QJsonDocument::Compact));
#endif
}
This works and I can see that int64Written is > 0 in the Application Output. The server application receives this message and sends and Ack:
bool blnDecodeHeartbeat(const QJsonObject& crobjJSON) {
QJsonObject::const_iterator citrFound = crobjJSON.find(clsJSON::mscszModule);
if ( citrFound == crobjJSON.end() ) {
return false;
}
QString strModuleName = citrFound.value().toString();
clsModule* pModule = clsModule::pGetModule(strModuleName);
if ( pModule == nullptr ) {
return false;
}
pModule->updateHearbeat();
//Send acknowledge back to module
QJsonObject objJSON;
objJSON.insert(clsJSON::mscszModule, strModuleName);
objJSON.insert(clsJSON::mscszMsgType, clsJSON::mscszAck);
//Cast the socket to the required type
emit pModule->sendJSON(objJSON);
return true;
}
This decode is called the instance the message arrives from the client and the sending of the Ack message is always successful. The server later tries to send a message to the client which is not the result of receiving a message:
void clsScriptHelper::notify(const QJsonObject& crobjModule
,QJsonObject objCmds) {
QJsonObject::const_iterator citrFound = crobjModule.find(clsJSON::mscszModule);
QString strModuleName;
clsModule* pModule;
if ( citrFound == crobjModule.end() ) {
return;
}
strModuleName = citrFound.value().toString();
//Make sure the module is set in the message
objCmds.insert(clsJSON::mscszModule, strModuleName);
//Set command type
objCmds.insert(clsJSON::mscszMsgType, clsJSON::mscszCmdNotify);
//Look up the socket for the module
pModule = clsModule::pGetModule(strModuleName);
if ( pModule == nullptr || pModule->blnTxAllowed() != true ) {
clsModule::sendLater(strModuleName, objCmds);
return;
}
//Convert object into byte array for transmission
emit pModule->sendJSON(objCmds);
}
The code to send Later:
void clsModule::sendLater(const QString& crstrModule, const QJsonObject& crobjJSON) {
mpSendLater::iterator itrList = clsModule::msmpSendLaterLst.find(crstrModule);
QJsonObject* pobjJSON;
if ( itrList != clsModule::msmpSendLaterLst.end() ) {
pobjJSON = itrList->second;
} else {
pobjJSON = new QJsonObject();
if ( pobjJSON != nullptr ) {
clsModule::msmpSendLaterLst.insert(std::make_pair(crstrModule, pobjJSON));
}
}
if ( pobjJSON != nullptr ) {
*pobjJSON = crobjJSON;
#if defined(DEBUG_SOCKETS)
QString strExpoded(clsJSON::strExplodeJSON(*pobjJSON, 0));
qdbg() << "clsModule::sendLater: " << strExpoded.toLatin1().data();
#endif
}
}
The purpose of this function is that if the client is not connected or not ready then it inserts the message into a map that is supposed to be transmitted when the client next connects.
When the client is connected the waiting messages are sent using the clsSocketClient::sendJSON as posted above, and this fails 100% of the time. Why?
Its as if the client isn't ready to receive a message. Typical output in Application Output:
D00000000000000000028T000000000915:clsJSON::commonDecode [50]: {"module":"mdFileIO","msgType":"init","port":8124}
W00000000000000000029T000000001334:QProcess::setProgram: Process is already running
D00000000000000000030T000000001334:Process: mdFileIO started, PID: 1046
D00000000000000000031T000000002816:clsJSON::commonDecode [49]: {"PID":"1046","module":"mdFileIO","msgType":"hb"}
D00000000000000000032T000000002816:clsSocketClient::sendJSON[41]:{"module":"mdFileIO","msgType":"ack"}
D00000000000000000033T000000002816:clsSocketClient::onBytesWritten:41
D00000000000000000034T000000004718:clsJSON::commonDecode [49]: {"PID":"1046","module":"mdFileIO","msgType":"hb"}
D00000000000000000035T000000004718:clsSocketClient::sendJSON[41]:{"module":"mdFileIO","msgType":"ack"}
D00000000000000000036T000000004718:clsSocketClient::onBytesWritten:41