Solved How to handle socket Transactions uncommitted ?
-
In my project , i need to distinguish the coming sockets contents . so i write the follow codes :
void ServerModule::SlotReadyRead(QObject* socketObject) { QTcpSocket *socket = qobject_cast<QTcpSocket *>(socketObject); if (!socket || !socket->bytesAvailable()) return; QDataStream in; in.setDevice(socket); in.setVersion(QDataStream::Qt_5_7); qint32 requestType = 0; in.startTransaction(); in >> requestType; switch (requestType) { case TransmissionType::clientConfig: { //do some work in>>other Serialized object; //add the sockets ip address to some container //add the coming objects into some container to manage } //other cases : } if (!in.commitTransaction()) { return; }
In most situation ,the code works well because the
!in.commitTransaction()
doesn't trigger .But some times happen that only one time can't get enough data to serialized one object then thereturn
function works . And the second time comes data finally serialized one object ,but the coming sockets add twice .So how to correctly write code with
startTransaction
andcommitTransaction
?more accurately , what's the right time to handle the coming serialized object ? because i need to distinguish content type , so i can't do all work after
commitTransaction
-
Most likely the problem occurs when only 1 to 3 bytes are in the buffer.
The issue that the readyRead signal is triggered when information is available to be read. However, no socket can know how many bytes to expect. Also there are timing issues with the event loop.
The result is that a slot routine connected to readyRead may find only part of the required information in the buffer. This might be anything between 1 Byte and a infinite number of bytes.Therefore you need to check that enough bytes are in the buffer before reading. In case not enough bytes are yet available you may return and wait for the next readyRead or you can use waitForReadyRead. The best choice depends on your actual connection, the frequency of in-coming data and your latency requirements.
-
@koahnig my project has GUI , so block method may not be suitable . Currently my solution is that change the container to those non-repeatable container .
-
@SpartaWHY117
@koahnig said in How to handle socket Transactions uncommitted ?:The best choice depends on your actual connection, the frequency of in-coming data and your latency requirements.
You could use waitForReadyRead for a short moment or you have to return from your slot and ensure that it is called again.
Note, that readyRead slot may be called with not enough bytes and therefore you may trigger a return. Depending on size of data and speed of CPU already all data may be present when you actually return. There is no guaranty that you receive directly another readyRead signal.