Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Usage of QDataStream in QTcpSocket

Usage of QDataStream in QTcpSocket

Scheduled Pinned Locked Moved Unsolved General and Desktop
2 Posts 2 Posters 1.7k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • G Offline
    G Offline
    Gerrard_queue
    wrote on last edited by
    #1

    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!

    jsulmJ 1 Reply Last reply
    0
    • G Gerrard_queue

      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!

      jsulmJ Offline
      jsulmJ Offline
      jsulm
      Lifetime Qt Champion
      wrote on last edited by jsulm
      #2

      @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.

      https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      3

      • Login

      • Login or register to search.
      • First post
        Last post
      0
      • Categories
      • Recent
      • Tags
      • Popular
      • Users
      • Groups
      • Search
      • Get Qt Extensions
      • Unsolved