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. QDataStream fail to send large strings
Forum Updated to NodeBB v4.3 + New Features

QDataStream fail to send large strings

Scheduled Pinned Locked Moved Unsolved General and Desktop
qdatastream
10 Posts 3 Posters 778 Views 1 Watching
  • 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.
  • D Offline
    D Offline
    Dariusz
    wrote on 21 Jan 2023, 16:40 last edited by
    #1

    Hey

    I'm on pyside2 5.15 qt. I'm trying to socket-QDataStream send string that is 500mb big...

    When I try to send it it just sends 4 bytes.

    Is the string size limited to socket buffer? Do I need to enable some kind of chunking?

    Regards
    Dariusz

    1 Reply Last reply
    0
    • C Offline
      C Offline
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on 21 Jan 2023, 16:48 last edited by
      #2

      Why should a string be 500MB large?
      How do you send it/receive it?

      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
      0
      • D Offline
        D Offline
        Dariusz
        wrote on 21 Jan 2023, 17:25 last edited by
        #3

        Sender

        port = 500
        
        socket = QTcpSocket()
        
        # Connect to the server
        socket.connectToHost("localhost", port)
        msg = str(uuid.uuid4())
        for a in range(0, 28):
            msg += msg
        print(len(msg) / 1024 / 1024)
        
        # Wait for the connection to be established
        if socket.waitForConnected(5000):
            print("sending...")
            # Create a QByteArray to hold the data
            data = QByteArray("Hello World!".encode())
            data = json.dumps({"hello": "world", "this": [{"this": "is"}, {"awe": "some"}],
                               "stupidLongStuff": msg,
                               "END": 1})
            # Create a QDataStream to write the data
            stream = QDataStream(socket)
            dataSize = len(data)
            print("sending data size : ", dataSize)
            # Write the data to the stream
            stream.writeInt32(dataSize)
            stream.writeString(str(data))
            # Wait for the data to be sent
            socket.waitForBytesWritten()
            print("Data sent successfully")
        else:
            print("Error:", socket.errorString())
        

        Receiver is just

            def _handleReadyRead(self):
                client_socket: QTcpSocket = self.sender()
                stream = QDataStream(client_socket)
                jobSize = client_socket.bytesAvailable()
                print("Thread dat : ", self.thread(), jobSize)
                size =  stream.readInt32()
                data = stream.readString()
        

        The int works fine, but string after is fail. No matter waht I try, dataStream wont push it.

        1 Reply Last reply
        0
        • C Offline
          C Offline
          Christian Ehrlicher
          Lifetime Qt Champion
          wrote on 21 Jan 2023, 18:03 last edited by
          #4

          readRead() is called when data is available at the socket, not when all data is received (what a socket can't know) so you have to reassemble your data by yourself.

          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
          • D Offline
            D Offline
            Dariusz
            wrote on 21 Jan 2023, 18:25 last edited by
            #5

            @Christian-Ehrlicher Should DataStream not deal with it? Handle chunking/etc/etc?

            Regards
            Dariusz

            C 1 Reply Last reply 21 Jan 2023, 18:27
            0
            • D Dariusz
              21 Jan 2023, 18:25

              @Christian-Ehrlicher Should DataStream not deal with it? Handle chunking/etc/etc?

              Regards
              Dariusz

              C Offline
              C Offline
              Christian Ehrlicher
              Lifetime Qt Champion
              wrote on 21 Jan 2023, 18:27 last edited by Christian Ehrlicher
              #6

              @Dariusz said in QDataStream fail to send large strings:

              Should DataStream not deal with it? Handle chunking/etc/etc?

              Why? "The QDataStream class provides serialization of binary data to a QIODevice" - nothing more and nothing less.

              You can look at the transaction support for QDataStream though.

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

              D 1 Reply Last reply 21 Jan 2023, 19:36
              1
              • C Christian Ehrlicher
                21 Jan 2023, 18:27

                @Dariusz said in QDataStream fail to send large strings:

                Should DataStream not deal with it? Handle chunking/etc/etc?

                Why? "The QDataStream class provides serialization of binary data to a QIODevice" - nothing more and nothing less.

                You can look at the transaction support for QDataStream though.

                D Offline
                D Offline
                Dariusz
                wrote on 21 Jan 2023, 19:36 last edited by
                #7

                @Christian-Ehrlicher Hmmm I think because its class is responsible for serializing/deserializing/managing data so I thought it would handle the chunking/etc with socket. Else it feels like half-measure and I still have to solve the chunking/disconnection/etc.

                1 Reply Last reply
                0
                • S Offline
                  S Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on 21 Jan 2023, 19:42 last edited by
                  #8

                  Hi,

                  QDataStream serializes something to a QIODevice. What happens after that is not its concern. For example, why would it need to know how to write to a socket more than knowing how to write to a file ? That's what the QIODevice are responsible for. If you need higher level structure management, make your own QIODevice.

                  Interested in AI ? www.idiap.ch
                  Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                  1 Reply Last reply
                  1
                  • C Offline
                    C Offline
                    Christian Ehrlicher
                    Lifetime Qt Champion
                    wrote on 21 Jan 2023, 19:43 last edited by
                    #9

                    Please read about the transactions.
                    Also writing this as a string is nonsense - it just doubles the size of transferred bytes for no reason. Just sent a bytearray directly. Also there is no need to send the dataSize since QDataStream adds this information to the stream by itself.

                    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
                    • D Offline
                      D Offline
                      Dariusz
                      wrote on 22 Jan 2023, 02:12 last edited by
                      #10

                      @Christian-Ehrlicher Hmmm I'm not having any luck with this method so far :/
                      Code below is self contained test. The DataStream is not commitTransaction and thus still waits for more data but never reads it/deals with it.
                      Socket dies, no more data comes in, handle_ready_read never gets called again, even if I force call again it wont read any more data... :/ Where am I hitting wall here?

                      import json
                      import uuid
                      from functools import partial
                      
                      from PySide2.QtNetwork import *
                      from PySide2.QtCore import *
                      from PySide2.QtWidgets import *
                      
                      
                      class BasicServer(QTcpServer):
                          s_newJob = Signal(object)
                      
                          def __init__(self, port: int):
                              QTcpServer.__init__(self)
                              self._mStatus = self.listen(QHostAddress.LocalHost, port)
                              self._mSocketList = {}
                              self._mJobs = {}
                              self.newConnection.connect(self._handleNewConnection)
                              print("Starting logic server on port : ", port, " Status : ", self._mStatus)
                              self._mTimer = QElapsedTimer()
                              self._mTimer.start()
                      
                          def getStatus(self) -> int:
                              return self._mStatus
                      
                          def _handleNewConnection(self):
                              client_socket: QTcpSocket = self.nextPendingConnection()
                              client_socket.readyRead.connect(partial(self.handle_ready_read, client_socket))
                              stream = QDataStream(client_socket)
                              self._mSocketList[client_socket] = [stream, QByteArray()]
                              client_socket.disconnected.connect(partial(self._handleSocketDisconnect, client_socket))
                      
                          def handle_ready_read(self, client_socket):
                              streamItem = self._mSocketList.get(client_socket, None)
                              if streamItem is None:
                                  return
                              print("reading?")
                              stream = streamItem[0]
                              stream.startTransaction()
                              streamData = streamItem[1]
                              stream >> streamData
                              print(len(streamData))
                              self._mSocketList[client_socket][1] = streamData
                              if not stream.commitTransaction():
                                  return
                              print("IM FINISH! ", streamData)
                      
                          def _handleSocketDisconnect(self, socketPtr: QTcpSocket):
                              print("Socket is gone...")
                              return  # for now keep socket "alive"
                              killPort = socketPtr.peerPort()
                              if killPort in self._mJobs:
                                  if not self._mJobs[killPort]["emitted"]:
                                      if self._mJobs[killPort]["toDownload"] == 0:
                                          pass
                                  del self._mJobs[killPort]
                      
                              if socketPtr in self._mSocketList:
                                  del self._mSocketList[socketPtr]
                              print("Killing socket", killPort, socketPtr)
                              socketPtr.deleteLater()
                      
                      
                      def clientTest():
                          port = 500
                      
                          socket = QTcpSocket()
                      
                          # Connect to the server
                          socket.connectToHost("localhost", port)
                          msg = str(uuid.uuid4())
                          for a in range(0, 10):
                              msg += msg
                          print(len(msg) / 1024 / 1024)
                      
                          # Wait for the connection to be established
                          if socket.waitForConnected(5000):
                              print("sending...")
                              # Create a QByteArray to hold the data
                              data = QByteArray("Hello World!".encode())
                              jDumped = json.dumps({"hello": "world", "this": [{"this": "is"}, {"awe": "some"}],
                                                    "stupidLongStuff": msg,
                                                    "END": 1})
                              data = QByteArray(jDumped.encode())
                      
                              # Create a QDataStream to write the data
                              stream = QDataStream(socket)
                              # stream.setVersion(QDataStream.Qt_5_15)
                              print("Data size : ", len(data))
                              stream << data
                              # stream.writeString("hellooo")
                              # dataSize = len(data)
                      
                              # print("sending data size : ", dataSize)
                              # Write the data to the stream
                              # stream.writeInt64(dataSize)
                              # socket.waitForBytesWritten()
                              # socket.write(struct.pack("l", len(data)))
                              # socket.write(data.encode())
                              socket.waitForBytesWritten()
                              print("Data sent successfully")
                          else:
                              print("Error:", socket.errorString())
                      
                      
                      app = QApplication([])
                      s = BasicServer(500)
                      
                      clientTest()
                      
                      app.exec_()
                      
                      1 Reply Last reply
                      0

                      4/10

                      21 Jan 2023, 18:03

                      • Login

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