Solved Two way comms via socket?
-
@KroMignon , thank you, I can see that, but what could it be?
Will launch WireShark and take a closer look.
[Edit] From WireShark:
0000 1e 00 00 00 60 03 01 5f 00 5a 06 40 00 00 00 00 ....`.._.Z.@.... 0010 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 ................ 0020 00 00 00 00 00 00 00 00 00 00 00 01 c5 84 1f bb ................ 0030 51 fb 74 49 39 86 cf 4c 80 18 18 e3 00 62 00 00 Q.tI9..L.....b.. 0040 01 01 08 0a 00 d9 d7 67 00 d9 d7 63 7b 22 61 64 .......g...c{"ad 0050 64 72 54 6f 22 3a 22 58 4d 4c 4d 50 41 4d 22 2c drTo":"XMLMPAM", 0060 22 6d 73 67 54 79 70 65 22 3a 22 72 65 61 64 79 "msgType":"ready 0070 22 2c 22 73 6f 75 72 63 65 22 3a 22 6d 64 46 69 ","source":"mdFi 0080 6c 65 49 4f 22 7d leIO"}
This is the initial module B message declaring that the module is now ready.
0000 1e 00 00 00 60 03 01 5f 00 57 06 40 00 00 00 00 ....`.._.W.@.... 0010 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 ................ 0020 00 00 00 00 00 00 00 00 00 00 00 01 c5 84 1f bb ................ 0030 51 fb 74 83 39 86 cf 4c 80 18 18 e3 00 5f 00 00 Q.t.9..L....._.. 0040 01 01 08 0a 00 d9 de cf 00 d9 d7 67 7b 22 61 64 ...........g{"ad 0050 64 72 54 6f 22 3a 22 58 4d 4c 4d 50 41 4d 22 2c drTo":"XMLMPAM", 0060 22 6d 73 67 54 79 70 65 22 3a 22 68 62 22 2c 22 "msgType":"hb"," 0070 73 6f 75 72 63 65 22 3a 22 6d 64 46 69 6c 65 49 source":"mdFileI 0080 4f 22 7d O"}
This is the heartbeat message sent from B to A.
0000 1e 00 00 00 60 03 01 5f 00 57 06 40 00 00 00 00 ....`.._.W.@.... 0010 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 ................ 0020 00 00 00 00 00 00 00 00 00 00 00 01 c5 84 1f bb ................ 0030 51 fb 74 f1 39 86 cf 4c 80 18 18 e3 00 5f 00 00 Q.t.9..L....._.. 0040 01 01 08 0a 00 d9 ee 18 00 d9 e6 4a 7b 22 61 64 ...........J{"ad 0050 64 72 54 6f 22 3a 22 58 4d 4c 4d 50 41 4d 22 2c drTo":"XMLMPAM", 0060 22 6d 73 67 54 79 70 65 22 3a 22 68 62 22 2c 22 "msgType":"hb"," 0070 73 6f 75 72 63 65 22 3a 22 6d 64 46 69 6c 65 49 source":"mdFileI 0080 4f 22 7d O"}
Another heartbeat message again from B to A these are sent once every second.
0000 1e 00 00 00 60 03 01 5f 00 57 06 40 00 00 00 00 ....`.._.W.@.... 0010 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 ................ 0020 00 00 00 00 00 00 00 00 00 00 00 01 c5 84 1f bb ................ 0030 51 fb 75 28 39 86 cf 4c 80 18 18 e3 00 5f 00 00 Q.u(9..L....._.. 0040 01 01 08 0a 00 d9 f5 e7 00 d9 ee 18 7b 22 61 64 ............{"ad 0050 64 72 54 6f 22 3a 22 58 4d 4c 4d 50 41 4d 22 2c drTo":"XMLMPAM", 0060 22 6d 73 67 54 79 70 65 22 3a 22 68 62 22 2c 22 "msgType":"hb"," 0070 73 6f 75 72 63 65 22 3a 22 6d 64 46 69 6c 65 49 source":"mdFileI 0080 4f 22 7d O"}
And another heartbeat message again B to A, there are plenty of these but no acknowledgements.
So the question changes now, since A is telling me that it has written 55 bytes with the bytesWritten signal, where is the data going?
-
@SPlatten said in Two way comms via socket?:
thank you, I can see that, but what could it be?
I can only guess, I don't know how you set up the QTcpSocket instance on server side:
- You did not connect
readyRead()
signal - the instance have been destroyed
- the QEventLoop used by the thread which is hosting the instance is locked
- there is a bug in the slots attached to
readyRead()
signal
- You did not connect
-
@KroMignon , A connections:
QTcpSocket* pSocket = new QTcpSocket(); //Set the ID qdbg() << "clsServer::run"; if( !pSocket->setSocketDescriptor(msckDescriptor) ) { //Something's wrong, we just emit a signal emit error(pSocket->error()); return; } //Connect socket and signal mpsckIncoming = pSocket; QObject::connect(mpsckIncoming, &QAbstractSocket::errorOccurred ,this, &clsServer::onErrorOccurred); QObject::connect(mpsckIncoming, &QAbstractSocket::disconnected ,this, &clsServer::onDisconnected); QObject::connect(mpsckIncoming, &QAbstractSocket::readyRead ,this, &clsServer::onReadyRead);
Initialisation on B of QTcpSocket:
mpsckReceiver = new QTcpSocket(); QObject::connect(mpsckReceiver, &QAbstractSocket::bytesWritten ,this, &clsModule::onBytesWritten); QObject::connect(mpsckReceiver, &QAbstractSocket::connected ,this, &clsModule::onConnected); QObject::connect(mpsckReceiver, &QAbstractSocket::readyRead ,this, &clsModule::onReadyRead); QObject::connect(mpsckReceiver, &QAbstractSocket::disconnected ,this, &clsModule::onDisconnected); if ( mpsckReceiver != nullptr && muint16Port > 0 ) { QAbstractSocket::SocketState eState = mpsckReceiver->state(); if ( eState != QAbstractSocket::HostLookupState && eState != QAbstractSocket::ConnectedState && eState != QAbstractSocket::ConnectingState ) { mpsckReceiver->connectToHost(QHostInfo::localHostName(), muint16Port); } }
-
@SPlatten said in Two way comms via socket?:
So the question changes now, since A is telling me that it has written 55 bytes with the bytesWritten signal, where is the data going?
Into the TCP socket output buffer, did you disable Naggle's algorithm or do a QTcpSocket::flush()?
[EDIT] By the way, are you sure you are capturing the right traffic on WireShark? (tcp port 8123)
-
@KroMignon , no what's Naggle's algorithm ?
Wireshark must be ok, because the only address and port I'm sending JSON on is 8123
A sample from Wireshark:
19 2.131440 ::1 ::1 TCP 131 50625 → 8123 [PSH, ACK] Seq=59 Ack=1 Win=407744 Len=55 TSval=15333115 TSecr=15331092
This is from 50625 -> 8123, no idea what 50625 is? Then immediately after this entry in Wireshark is:
20 2.131460 ::1 ::1 TCP 76 8123 → 50625 [ACK] Seq=1 Ack=114 Win=407680 Len=0 TSval=15333115 TSecr=15333115
-
@SPlatten said in Two way comms via socket?:
no what's Naggle's algorithm ?
As written earlier (https://forum.qt.io/post/639857), this is the TCP algorithm which handles transmission rules to avoid sending too much small packets.
-
@SPlatten said in Two way comms via socket?:
what's Naggle's algorithm ?
It's
Nagle
's algorithm, as @KroMignon wrote :)However, it is "unusual" to disable this on a socket, it defaults to on for a good reason. If @KroMignon says
You have to call
QTcpSocket::flush()
to force data sending to counterpart.and that works I would use that rather then changing the socket option....
-
@JonB said in Two way comms via socket?:
However, it is "unusual" to disable this on a socket
It depends, there are always use cases for this: localhost or local network sockets
-
@JonB , I've added:
psckReceiver->flush();
After write and also added the call to:
mpsckReceiver = new QTcpSocket(); mpsckReceiver->setSocketOption(QAbstractSocket::LowDelayOption, 1);
Still the same, A is receiving but the Ack message is not appearing in WireShark.
-
@SPlatten
Then by all means try the socket option, as I said I don't know whether that has the same effect. Once neither flushing nor disabling Nagle works, whatever your issue it is something else. -
@SPlatten said in Two way comms via socket?:
Still the same, A is receiving but the Ack message is not appearing in WireShark.
So there are not so many options in my eyes:
- you are sending on wrong socket
- the socket is closed (did you check return value of
QTcpSocket::write()
?) - the event loop is locked,
QTcpSocket
requires a working event queue to work.
-
@KroMignon , I modified the onSendJSON slot:
void clsModule::onSendAck(const QJsonObject& crobjJSON, QTcpSocket* psckReceiver) { QJsonObject::const_iterator citrFound = crobjJSON.find(clsJSON::mscszMsgType); if ( citrFound == crobjJSON.end() ) { return; } QString strAck(clsJSON::mscszAck + citrFound.value().toString()); QJsonObject objAck; objAck.insert(clsJSON::mscszAddrTo, cstrGetAlias()); objAck.insert(clsJSON::mscszMsgType, strAck); objAck.insert(clsJSON::mscszSource, clsJSON::mscszXMLMPAM); qdbg() << "clsModule::onSendAck: " << QJsonDocument(objAck).toJson(QJsonDocument::Compact); if ( mblnReady != true ) { sendLater(cstrGetAlias(), objAck); } else if ( psckReceiver != nullptr ) { QAbstractSocket::SocketState eState(psckReceiver->state()); if ( eState == QAbstractSocket::ConnectedState ) { QByteArray arybytMsg(QJsonDocument(objAck).toJson(QJsonDocument::Compact)); qint64 int64Write = psckReceiver->write(arybytMsg); qdbg() << "clsModule::onSendAck, int64Write: " << int64Write; psckReceiver->flush(); } } }
Now its working, annoyingly I'm not sure what I've changed that has fixed it...Thank you to @KroMignon and @JonB.