Solved QTcpSocket read issue : using generic C/C++ technique
-
Hi All,
I am new in QT environment, and I have to create a client application to send message and receive the response from server. So far I have successfully implemented the request parser and sent the request message to our test server correctly.
Now I have to read the response against that request. To do this I have coded the read function like standard C/C++ but the data read size is always returned as zero. Please note that the response size is not static but maximum buffer can be assigned, and the response time may also very if server is doing any priority task (say between 1-10 seconds)Following is my code to write/read and display the response as initial confirmation :
unsigned char SENDBUF[3072];// Transmit buffer unsigned char RECVBUF[3072];// Receive buffer onConnectionEstablished(){ m_pTcpSocket->write ( (const char *) SENDBUF , SendMsgLen); m_pTcpSocket->waitForBytesWritten(10 * oneSecond); //Read Data **readTcpData();** m_pTcpSocket->disconnectFromHost(); m_pTcpSocket = 0; }
readTcpData()
{ std::cout << "\nReceiving response" << std::endl; if(m_pTcpSocket->bytesAvailable()> 0){ RecvMsgLen = m_pTcpSocket->read((char *) RECVBUF, 3072); } std::cout << "Receive message length = "<< RecvMsgLen << std::endl; QString txnData = getStringFromUnsignedChar(RECVBUF, RecvMsgLen); std::cout << txnData.toLocal8Bit().constData() << std::endl; }
Client output
State change to the socket is performing a host name lookup State change to CONNECTING Connecting outside: 178.153.243.220 State change to a connection is established Connected: 178.153.xxx.220 Message Sent: 00416030300000392e303139393939393930312020202020202020202020202020303731313137313133313134414f35303030303030301c6830303130303030303131 Receiving response Receive message length = 0 //'----
What I am noticing is that client is closing tcp socketbefore the request is received abd parsed by host, although I have added
(bytesAvailable()> 0)
condition.Thanks
[Added code tags ~kshegunov]
-
@Kashif Using the synchronus approach to QTCPSocket is not something I would recommand. However to fix your problem.
You actually dont wait for any bytes beeing available. The if part in readTcpData, simply skips if there are no bytes available and the function goes on and eventually out of skope
readTcpData() { std::cout << "\nReceiving response" << std::endl; if(m_pTcpSocket->bytesAvailable()> 0){ RecvMsgLen = m_pTcpSocket->read((char *) RECVBUF, 3072); } std::cout << "Receive message length = "<< RecvMsgLen << std::endl; QString txnData = getStringFromUnsignedChar(RECVBUF, RecvMsgLen); std::cout << txnData.toLocal8Bit().constData() << std::endl; }
The simplest solution: Add WaitforReadyRead
readTcpData() { std::cout << "\nReceiving response" << std::endl; if(m_pTcpSocket->bytesAvailable() == 0){ m_pTcpSocket->waitForReadyRead(1000) //Max wait time 1 Second } RecvMsgLen = m_pTcpSocket->read((char *) RECVBUF, 3072); std::cout << "Receive message length = "<< RecvMsgLen << std::endl; QString txnData = getStringFromUnsignedChar(RECVBUF, RecvMsgLen); std::cout << txnData.toLocal8Bit().constData() << std::endl; }
The better solution: use the QTcpSocket Signals for a asynchonus communication.
-
Hi @J.Hilk ,
Thanks for the solution, it works for me. The reason to use synchronous communication is because I am new in this environment and initially I have to build a working demo application for embedded Linux device using 3G communication. Once the solution is working we'll work for its optimization and also multi threading techniques.
Once again thanks for your support.
-
Hi @Kashif.
The QThread class provides a platform-independent way to manage threads.
For more detail http://doc.qt.io/qt-4.8/qthread.html#detailsQT5 TUTORIAL ASYNCHRONOUS QTCPSERVER WITH QTHREADPOOL - 2017
http://www.bogotobogo.com/Qt/Qt5_Asynchronous_QTcpServer_QThreadPool.php
http://www.bogotobogo.com/Qt/Qt5_QTcpServer_Multithreaded_Client_Server.php
it is good example, but it is writing only Qt c++.