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. do multiple calls to write of QTcpSocket/QWebSocket overwrite previous bytes which are not yet written?
QtWS25 Last Chance

do multiple calls to write of QTcpSocket/QWebSocket overwrite previous bytes which are not yet written?

Scheduled Pinned Locked Moved Solved General and Desktop
qtcpsocketqwebsockettcpnetworking
11 Posts 3 Posters 2.0k 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.
  • N Offline
    N Offline
    noone
    wrote on 23 Feb 2020, 14:35 last edited by
    #1

    hello there. sorry to bother you again.
    I have a few questions about QTcpSocket and QWebSocket

    When the write function of QTcpSocket is called, it doesn't write all bytes instantaneously but stores it in some sort of buffer, right? So When I call write multiple times while there are still some bytes to be written, are previous bytes which are not yet written are overwritten?

    Also, multiple calls to sendBinaryMessage of QWebSocket overwrite previous bytes which are not yet written?

    if bytes are not overwritten then in which order does the QByteArray objects are read by the client ? for example in the following situation on the server with QWebSocket

    socket.sendBinaryMessage(MyQByteArray1);
    socket.sendBinaryMessage(MyQByteArray2);
    socket.sendBinaryMessage(MyQByteArray3);
    

    will binaryMessageReceived signals contain QByteArray objects which are the same as those on the server-side in sequence? something like?

    binaryMessageReceived(MyQByteArray1);
    binaryMessageReceived(MyQByteArray2);
    binaryMessageReceived(MyQByteArray3);
    

    or do they arrive in random order?

    1 Reply Last reply
    0
    • N Offline
      N Offline
      noone
      wrote on 23 Feb 2020, 19:32 last edited by noone
      #9

      Hi,
      I done some testing with QWebSocket and QWebSocketServer. basically I send 3 Images from client to server of the following size 5 times without waiting for bytes to write

      $ du -h *.jpg                             
      35M     c0.jpg
      56K     c1.jpg
      30M     c.jpg
      

      client.cpp:-

      #include <QApplication>
      #include <QImage>
      #include <QWebSocket>
      #include <QDataStream>
      #include <QLabel>
      #include <QAbstractSocket>
      #include <QFile>
      
      void onConnected(QWebSocket *socket,QString str){
          QFile imgfile(str);
          imgfile.open(QIODevice::ReadOnly);
      
          QByteArray buf;
          QDataStream stream(&buf,QIODevice::WriteOnly);
      
          socket->sendBinaryMessage(imgfile.readAll());
          socket->flush();
      }
      
      int main(int argc, char *argv[]) {
          QApplication a(argc, argv);
          QWebSocket *socket = new QWebSocket;
          socket->open(QUrl("ws://127.0.0.1:1718"));
      
          QObject::connect(socket, &QWebSocket::disconnected, [socket]() {
              qDebug() << socket->errorString();
          });
      
          QObject::connect(socket,&QWebSocket::connected,[socket]{
              for(int i=0; i<5;i++){
                  onConnected(socket,"c.jpg");
                  onConnected(socket,"c0.jpg");
                  onConnected(socket,"c1.jpg");
              }
          });
      
          return a.exec();
      }
      

      server.cpp:-

      #include <QApplication>
      #include <QWebSocket>
      #include <QHostAddress>
      #include <QWebSocketServer>
      #include <QLabel>
      #include <QFile>
      
      int main(int argc, char *argv[])
      {
          QApplication a(argc, argv);
      
          QWebSocketServer server(QStringLiteral("My server"),QWebSocketServer::SslMode::NonSecureMode);
      
          if(!server.listen(QHostAddress::Any,1718)){
              qDebug() << server.errorString() ;
              return -1;
          }
      
          qDebug() << server.serverUrl().toString();
      
          QObject::connect(&server, &QWebSocketServer::newConnection,[&server](){
      
              static int i=100;
      
              qDebug() << "new connection";
              QWebSocket *pSocket = server.nextPendingConnection();
      
              QObject::connect(pSocket, &QWebSocket::binaryMessageReceived, [](const QByteArray &rawimg){
                  auto img = QImage::fromData(rawimg,"JPG");
                  QLabel *myLabel = new QLabel;
                  myLabel->setPixmap(QPixmap::fromImage(img));
                  myLabel->show();
                  QFile file(QString::number(i++));
                  file.open(QFile::WriteOnly);
      
                  file.write(rawimg);
              });
          });
      
          return a.exec();
      }
      

      When I run this program, I can see with the help of title name <server*> of windows and new images in server directory, that images are displayed and written on disk in order in which they were sent from the client.

      This marks my original question answered. So I am marking this as solved

      But btw when I ran server and client, something weird happened.
      when I ran server and client, my laptop became unresponsive for a minute. I couldn't even reach tty to kill server and client. the audio was still playing in the meantime. after a minute, it became responsive again. Then I killed the server and client and got this (I always leave it running in background) :-

      Screenshot_20200224_003741.png

      it nearly filled my RAM and on top of that, it also consumed 6GB of the swap. my swap doesn't even get filled with 1KB normally. is this normal ? am I doing something wrong?

      M 1 Reply Last reply 23 Feb 2020, 20:20
      0
      • C Offline
        C Offline
        Christian Ehrlicher
        Lifetime Qt Champion
        wrote on 23 Feb 2020, 14:39 last edited by
        #2

        @noone said in do multiple calls to write of QTcpSocket/QWebSocket overwrite previous bytes which are not yet written?:

        So When I call write multiple times while there are still some bytes to be written, are previous bytes which are not yet written are overwritten?

        No, why should this happen?

        Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
        Visit the Qt Academy at https://academy.qt.io/catalog

        1 Reply Last reply
        1
        • N Offline
          N Offline
          noone
          wrote on 23 Feb 2020, 15:25 last edited by noone
          #3

          @Christian-Ehrlicher I guess this should not happen. So I should not write until the previous bytes is written? I am really new this stuff and so much confused

          M 1 Reply Last reply 23 Feb 2020, 15:34
          0
          • N noone
            23 Feb 2020, 15:25

            @Christian-Ehrlicher I guess this should not happen. So I should not write until the previous bytes is written? I am really new this stuff and so much confused

            M Offline
            M Offline
            mrjj
            Lifetime Qt Champion
            wrote on 23 Feb 2020, 15:34 last edited by mrjj
            #4

            @noone

            Hi
            On most devices, the sending buffer (in the network layer) is big enough
            that you should never have to worry about that and just send as you like.
            It should never overwrite anything.

            The things you send will/should come in the same order as when you send it.

            N 1 Reply Last reply 23 Feb 2020, 15:43
            2
            • M mrjj
              23 Feb 2020, 15:34

              @noone

              Hi
              On most devices, the sending buffer (in the network layer) is big enough
              that you should never have to worry about that and just send as you like.
              It should never overwrite anything.

              The things you send will/should come in the same order as when you send it.

              N Offline
              N Offline
              noone
              wrote on 23 Feb 2020, 15:43 last edited by noone
              #5

              @mrjj So does it mean I can call write() multiple times without polling bytesToWrite() ?

              M 1 Reply Last reply 23 Feb 2020, 15:45
              0
              • N noone
                23 Feb 2020, 15:43

                @mrjj So does it mean I can call write() multiple times without polling bytesToWrite() ?

                M Offline
                M Offline
                mrjj
                Lifetime Qt Champion
                wrote on 23 Feb 2020, 15:45 last edited by mrjj
                #6

                @noone
                Yes I would think so unless the WebSocket protocol has some limitation which i think the docs would
                have mentioned then. Or maybe if your message is extremely huge.

                N 1 Reply Last reply 23 Feb 2020, 15:54
                1
                • M mrjj
                  23 Feb 2020, 15:45

                  @noone
                  Yes I would think so unless the WebSocket protocol has some limitation which i think the docs would
                  have mentioned then. Or maybe if your message is extremely huge.

                  N Offline
                  N Offline
                  noone
                  wrote on 23 Feb 2020, 15:54 last edited by noone
                  #7

                  @mrjj

                  if your message is extremely huge.

                  I want to send some data from the QSqlDatabase along with multiple (Q)images, they might be in KBs or In MBs. If I serialize multiple QImages with QDatastream then it would easily become more than ~20MB

                  M 1 Reply Last reply 23 Feb 2020, 16:12
                  0
                  • N noone
                    23 Feb 2020, 15:54

                    @mrjj

                    if your message is extremely huge.

                    I want to send some data from the QSqlDatabase along with multiple (Q)images, they might be in KBs or In MBs. If I serialize multiple QImages with QDatastream then it would easily become more than ~20MB

                    M Offline
                    M Offline
                    mrjj
                    Lifetime Qt Champion
                    wrote on 23 Feb 2020, 16:12 last edited by
                    #8

                    @noone
                    Hi
                    That should work fine.
                    I'm not that familiar with WebSocket protocol if it also will issue multiple
                    binaryMessageReceived signal pr message if the message is large or if that is handled internally and will first trigger binaryMessageReceived signal when all is received.
                    You should test it out with one and see.

                    1 Reply Last reply
                    0
                    • N Offline
                      N Offline
                      noone
                      wrote on 23 Feb 2020, 19:32 last edited by noone
                      #9

                      Hi,
                      I done some testing with QWebSocket and QWebSocketServer. basically I send 3 Images from client to server of the following size 5 times without waiting for bytes to write

                      $ du -h *.jpg                             
                      35M     c0.jpg
                      56K     c1.jpg
                      30M     c.jpg
                      

                      client.cpp:-

                      #include <QApplication>
                      #include <QImage>
                      #include <QWebSocket>
                      #include <QDataStream>
                      #include <QLabel>
                      #include <QAbstractSocket>
                      #include <QFile>
                      
                      void onConnected(QWebSocket *socket,QString str){
                          QFile imgfile(str);
                          imgfile.open(QIODevice::ReadOnly);
                      
                          QByteArray buf;
                          QDataStream stream(&buf,QIODevice::WriteOnly);
                      
                          socket->sendBinaryMessage(imgfile.readAll());
                          socket->flush();
                      }
                      
                      int main(int argc, char *argv[]) {
                          QApplication a(argc, argv);
                          QWebSocket *socket = new QWebSocket;
                          socket->open(QUrl("ws://127.0.0.1:1718"));
                      
                          QObject::connect(socket, &QWebSocket::disconnected, [socket]() {
                              qDebug() << socket->errorString();
                          });
                      
                          QObject::connect(socket,&QWebSocket::connected,[socket]{
                              for(int i=0; i<5;i++){
                                  onConnected(socket,"c.jpg");
                                  onConnected(socket,"c0.jpg");
                                  onConnected(socket,"c1.jpg");
                              }
                          });
                      
                          return a.exec();
                      }
                      

                      server.cpp:-

                      #include <QApplication>
                      #include <QWebSocket>
                      #include <QHostAddress>
                      #include <QWebSocketServer>
                      #include <QLabel>
                      #include <QFile>
                      
                      int main(int argc, char *argv[])
                      {
                          QApplication a(argc, argv);
                      
                          QWebSocketServer server(QStringLiteral("My server"),QWebSocketServer::SslMode::NonSecureMode);
                      
                          if(!server.listen(QHostAddress::Any,1718)){
                              qDebug() << server.errorString() ;
                              return -1;
                          }
                      
                          qDebug() << server.serverUrl().toString();
                      
                          QObject::connect(&server, &QWebSocketServer::newConnection,[&server](){
                      
                              static int i=100;
                      
                              qDebug() << "new connection";
                              QWebSocket *pSocket = server.nextPendingConnection();
                      
                              QObject::connect(pSocket, &QWebSocket::binaryMessageReceived, [](const QByteArray &rawimg){
                                  auto img = QImage::fromData(rawimg,"JPG");
                                  QLabel *myLabel = new QLabel;
                                  myLabel->setPixmap(QPixmap::fromImage(img));
                                  myLabel->show();
                                  QFile file(QString::number(i++));
                                  file.open(QFile::WriteOnly);
                      
                                  file.write(rawimg);
                              });
                          });
                      
                          return a.exec();
                      }
                      

                      When I run this program, I can see with the help of title name <server*> of windows and new images in server directory, that images are displayed and written on disk in order in which they were sent from the client.

                      This marks my original question answered. So I am marking this as solved

                      But btw when I ran server and client, something weird happened.
                      when I ran server and client, my laptop became unresponsive for a minute. I couldn't even reach tty to kill server and client. the audio was still playing in the meantime. after a minute, it became responsive again. Then I killed the server and client and got this (I always leave it running in background) :-

                      Screenshot_20200224_003741.png

                      it nearly filled my RAM and on top of that, it also consumed 6GB of the swap. my swap doesn't even get filled with 1KB normally. is this normal ? am I doing something wrong?

                      M 1 Reply Last reply 23 Feb 2020, 20:20
                      0
                      • N noone
                        23 Feb 2020, 19:32

                        Hi,
                        I done some testing with QWebSocket and QWebSocketServer. basically I send 3 Images from client to server of the following size 5 times without waiting for bytes to write

                        $ du -h *.jpg                             
                        35M     c0.jpg
                        56K     c1.jpg
                        30M     c.jpg
                        

                        client.cpp:-

                        #include <QApplication>
                        #include <QImage>
                        #include <QWebSocket>
                        #include <QDataStream>
                        #include <QLabel>
                        #include <QAbstractSocket>
                        #include <QFile>
                        
                        void onConnected(QWebSocket *socket,QString str){
                            QFile imgfile(str);
                            imgfile.open(QIODevice::ReadOnly);
                        
                            QByteArray buf;
                            QDataStream stream(&buf,QIODevice::WriteOnly);
                        
                            socket->sendBinaryMessage(imgfile.readAll());
                            socket->flush();
                        }
                        
                        int main(int argc, char *argv[]) {
                            QApplication a(argc, argv);
                            QWebSocket *socket = new QWebSocket;
                            socket->open(QUrl("ws://127.0.0.1:1718"));
                        
                            QObject::connect(socket, &QWebSocket::disconnected, [socket]() {
                                qDebug() << socket->errorString();
                            });
                        
                            QObject::connect(socket,&QWebSocket::connected,[socket]{
                                for(int i=0; i<5;i++){
                                    onConnected(socket,"c.jpg");
                                    onConnected(socket,"c0.jpg");
                                    onConnected(socket,"c1.jpg");
                                }
                            });
                        
                            return a.exec();
                        }
                        

                        server.cpp:-

                        #include <QApplication>
                        #include <QWebSocket>
                        #include <QHostAddress>
                        #include <QWebSocketServer>
                        #include <QLabel>
                        #include <QFile>
                        
                        int main(int argc, char *argv[])
                        {
                            QApplication a(argc, argv);
                        
                            QWebSocketServer server(QStringLiteral("My server"),QWebSocketServer::SslMode::NonSecureMode);
                        
                            if(!server.listen(QHostAddress::Any,1718)){
                                qDebug() << server.errorString() ;
                                return -1;
                            }
                        
                            qDebug() << server.serverUrl().toString();
                        
                            QObject::connect(&server, &QWebSocketServer::newConnection,[&server](){
                        
                                static int i=100;
                        
                                qDebug() << "new connection";
                                QWebSocket *pSocket = server.nextPendingConnection();
                        
                                QObject::connect(pSocket, &QWebSocket::binaryMessageReceived, [](const QByteArray &rawimg){
                                    auto img = QImage::fromData(rawimg,"JPG");
                                    QLabel *myLabel = new QLabel;
                                    myLabel->setPixmap(QPixmap::fromImage(img));
                                    myLabel->show();
                                    QFile file(QString::number(i++));
                                    file.open(QFile::WriteOnly);
                        
                                    file.write(rawimg);
                                });
                            });
                        
                            return a.exec();
                        }
                        

                        When I run this program, I can see with the help of title name <server*> of windows and new images in server directory, that images are displayed and written on disk in order in which they were sent from the client.

                        This marks my original question answered. So I am marking this as solved

                        But btw when I ran server and client, something weird happened.
                        when I ran server and client, my laptop became unresponsive for a minute. I couldn't even reach tty to kill server and client. the audio was still playing in the meantime. after a minute, it became responsive again. Then I killed the server and client and got this (I always leave it running in background) :-

                        Screenshot_20200224_003741.png

                        it nearly filled my RAM and on top of that, it also consumed 6GB of the swap. my swap doesn't even get filled with 1KB normally. is this normal ? am I doing something wrong?

                        M Offline
                        M Offline
                        mrjj
                        Lifetime Qt Champion
                        wrote on 23 Feb 2020, 20:20 last edited by mrjj
                        #10

                        Hi
                        It sounds like you have a memory leak somewhere.

                        Things like
                        QLabel *myLabel = new QLabel; << you assign it no parent so it won't be deleted by the parent.

                        You could use
                        myLabel->setAttribute(Qt::WA_DeleteOnClose);

                        If it pops up the image and you close it by pressing X

                        Its should not normally use all your memory and 6GB swap :)

                        oh, the image is 35M !!!
                        ok so I guess its just the QLabel not being deleted and it gets a copy of the image so
                        you dont have to send those 3 images many times to eat lots of memory :)

                        1 Reply Last reply
                        2
                        • N Offline
                          N Offline
                          noone
                          wrote on 24 Feb 2020, 05:24 last edited by
                          #11

                          after removing the lines:-

                          auto img = QImage::fromData(rawimg);
                          QLabel *myLabel = new QLabel;
                          myLabel->setPixmap(QPixmap::fromImage(img));
                          myLabel->show();
                          

                          it works perfectly with more than 20*3 images

                          1 Reply Last reply
                          0

                          5/11

                          23 Feb 2020, 15:43

                          • Login

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