Usage of QDataStream in QTcpSocket
-
I want to do a two-way communication between a client and a server.
In my design, the client first sends out a request message. Then the server reads the request message and response correspondingly. I use multithreading to handle multiple clients, but now I just test on one client connection to the server.
Now, the client can send out the request message, and the server can read it, but the client never receives the response sent by the server.client:
//... //some other codes before QTcpSocket tcpsocket; tcpsocket.connectToHost(sources[0], fport); // source[0] contains a host address, fport stores the port if(!tcpsocket.waitForConnected(5000)){ qDebug() <<"WaitforConnected fails"<< "TCP Connection fails" << tcpsocket.errorString(); break; } QString requestFile(temp.c_str()); //temp is a filename QByteArray block; QByteArray inblock; QDataStream out(&block, QIODevice::WriteOnly); out.setVersion(QDataStream::Qt_5_11); out << (quint32)0 << requestFile; tcpsocket.write(block); tcpsocket.flush(); tcpsocket.waitForBytesWritten(); //read the server response QDataStream in(&tcpsocket); in.setVersion(QDataStream::Qt_5_11); do { if (!tcp.waitForReadyRead(5000)) { emit error(tcpsocket.error(), tcpsocket.errorString()); //get "operation timeout" or "remote host close the connection" here break; } in.startTransaction(); in >> inblock; qDebug() << inblock.size(); //always 0 } while (!in.commitTransaction()); //other codes below //...
server:
void ServerThread::run(){ QTcpSocket tcp; //socketDesciptor passed by the override incomingConnection() function in the QTcpServer and pass the socketDesciptor to a new QThread, then starts the thread if(!tcp.setSocketDescriptor(socketDesciptor)){ emit error(tcp.error(), tcp.errorString()); return; } QDataStream in(&tcp); in.setVersion(QDataStream::Qt_5_11); quint32 pos; QString filename; do { if (!tcp.waitForReadyRead(5000)) { emit error(tcp.error(), tcp.errorString()); return; } in.startTransaction(); in >> pos >> filename; //pos and filename can be successfully read } while (!in.commitTransaction()); if(pos == (quint32)0){ QFile f(filename); if(!f.open(QIODevice::ReadOnly)){ return; } //send back response to the client f.seek(0); QByteArray bb = f.read(44); qDebug() << tcp.write(bb); //output 44, which is expected tcp.waitForBytesWritten(); } else return; }
I am a newbie in both Qt and tcp, and will appreciate any comments about the codes. Thank you!
-
@Gerrard_queue said in Usage of QDataStream in QTcpSocket:
if (!tcp.waitForReadyRead(5000)) {
I would remove this part from server as it would terminate the server when no client connects for 5 seconds. Also it is better to use asynchronous API (signals/slots) instead of blocking calls.
Also you should connect a slot to http://doc.qt.io/qt-5/qabstractsocket.html#error-1 to see whether there are any errors.