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 serialization of objects over QTcpSocket
QtWS25 Last Chance

QDataStream serialization of objects over QTcpSocket

Scheduled Pinned Locked Moved Solved General and Desktop
10 Posts 4 Posters 4.4k 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.
  • D Offline
    D Offline
    DRoscoe
    wrote on last edited by
    #1

    I am exploring using QDataStream serialization of objects over a TCP socket. I see many examples which use files, but it is unclear to me how this extends to socket transfer. In the examples I see, the authors typically do not send size information over the stream. This works fine for files, but with sockets, I can't guarantee all of the data needed to deserialize an object has been transmitted. How then do I ensure that I have complete data prior to attempting deserialization? Do I have to figure out the serialized sizes of all my data objects and encode it on the stream? Are there any examples of serializing user-defined objects over TCP socket using QDataStream?

    1 Reply Last reply
    0
    • mrjjM Offline
      mrjjM Offline
      mrjj
      Lifetime Qt Champion
      wrote on last edited by
      #2

      @DRoscoe said:

      QDataStream

      When streaming something the actual format is always open.
      One options is to use a fixed size header so that you will know when u have
      received the expected amount. this header could then define a size for
      the rest of the data or define a end of transmission byte.
      Other options include serialize to json and send that over the wire.
      If u stream "raw" object members then extra care for strings or composite types
      must be handled in both ends.
      Pointers also pose a case.

      D 1 Reply Last reply
      2
      • mrjjM mrjj

        @DRoscoe said:

        QDataStream

        When streaming something the actual format is always open.
        One options is to use a fixed size header so that you will know when u have
        received the expected amount. this header could then define a size for
        the rest of the data or define a end of transmission byte.
        Other options include serialize to json and send that over the wire.
        If u stream "raw" object members then extra care for strings or composite types
        must be handled in both ends.
        Pointers also pose a case.

        D Offline
        D Offline
        DRoscoe
        wrote on last edited by
        #3

        @mrjj I was afraid of that. This is for a messaging system where we have our main application sending messages to a client. Currently, we have a home-grown XML-based serialization/deserialization approach which flattens out our data structures to text for transmission and reconstitution on the other side. This makes it easy to determine total xfer size, but its also inefficient. If I were to use JSON, then I'm recreating our current approach with one that is very similar. I am hoping to eventually supplant our home-grown XML-based serialization/deserialization approach with a Qt solution.

        In any case, you've answered my question. Since we are using a fixed-size header which includes the total bytes expected, I could use the QDataStream to tell me the bytes available after serialization and backfill that information in the header. I just wasn't sure there wasn't a different approach since I could not find anything specific to serialization over a socket.

        1 Reply Last reply
        0
        • mrjjM Offline
          mrjjM Offline
          mrjj
          Lifetime Qt Champion
          wrote on last edited by
          #4

          well if u already use XML then json would/might only decrease the traffic some % and maybe be slightly lighter depending on the xml lib used.

          Is the current XML implementation too slow ?

          D 1 Reply Last reply
          1
          • mrjjM mrjj

            well if u already use XML then json would/might only decrease the traffic some % and maybe be slightly lighter depending on the xml lib used.

            Is the current XML implementation too slow ?

            D Offline
            D Offline
            DRoscoe
            wrote on last edited by
            #5

            @mrjj I have a few reasons for looking into this. The libraries we use for messaging bring in a lot of dependencies that prevent it from being convenient for other consumers (apps) to use. If I were to switch to a Qt-centric approach using QDataStream, I could reduce this dependency to a small library defining the common elements for messaging, and then allow anyone who wants to create/send/receive messages to define their own, without incurring all of the current dependency overhead. From what I am reading, the QDataStream encodes most data types as binary, which would be more efficient with respect to traffic, and finally, our XML-based approach is very inefficient in its own right and somewhat clunky to use for anything but the simplest of class objects. I would prefer replacing it with a backbone that is community updated, maintained, optimized and debugged than keeping our home-grown approach

            kshegunovK 1 Reply Last reply
            0
            • SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote on last edited by
              #6

              Hi,

              Depending on your needs QtRemoteObjects might be of interest.

              What about solutions like protobuf ?

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

              D 1 Reply Last reply
              2
              • D DRoscoe

                @mrjj I have a few reasons for looking into this. The libraries we use for messaging bring in a lot of dependencies that prevent it from being convenient for other consumers (apps) to use. If I were to switch to a Qt-centric approach using QDataStream, I could reduce this dependency to a small library defining the common elements for messaging, and then allow anyone who wants to create/send/receive messages to define their own, without incurring all of the current dependency overhead. From what I am reading, the QDataStream encodes most data types as binary, which would be more efficient with respect to traffic, and finally, our XML-based approach is very inefficient in its own right and somewhat clunky to use for anything but the simplest of class objects. I would prefer replacing it with a backbone that is community updated, maintained, optimized and debugged than keeping our home-grown approach

                kshegunovK Offline
                kshegunovK Offline
                kshegunov
                Moderators
                wrote on last edited by kshegunov
                #7

                @DRoscoe
                There are two approaches to this:

                1. Develop a protocol (this entails having special sequences to mark begin/end of message) and parsing them on reception. Usually it's a cumbersome approach to do if you're only interested to send a few objects. Which leads to:
                2. Send size information before the message so you know how much data you expect at the other end.

                As for the serialization/deserialization you can look up here and here. Also note that sending binary data over network when running on different platforms implies care for endianness and for the version of QDataStream.

                If you're interested in implementing it yourself, you could also peak at a project of mine (hadn't had the time to finish it properly, but it's a start) which deals with exactly such a problem, only the medium is a bit different but this is of no consequence here.

                Of course what @SGaist suggested is also a possibility if you are willing to allow for the additional dependency (which I assume you are, since you say currently you have more than one).

                Kind regards.

                Read and abide by the Qt Code of Conduct

                D 1 Reply Last reply
                2
                • kshegunovK kshegunov

                  @DRoscoe
                  There are two approaches to this:

                  1. Develop a protocol (this entails having special sequences to mark begin/end of message) and parsing them on reception. Usually it's a cumbersome approach to do if you're only interested to send a few objects. Which leads to:
                  2. Send size information before the message so you know how much data you expect at the other end.

                  As for the serialization/deserialization you can look up here and here. Also note that sending binary data over network when running on different platforms implies care for endianness and for the version of QDataStream.

                  If you're interested in implementing it yourself, you could also peak at a project of mine (hadn't had the time to finish it properly, but it's a start) which deals with exactly such a problem, only the medium is a bit different but this is of no consequence here.

                  Of course what @SGaist suggested is also a possibility if you are willing to allow for the additional dependency (which I assume you are, since you say currently you have more than one).

                  Kind regards.

                  D Offline
                  D Offline
                  DRoscoe
                  wrote on last edited by
                  #8

                  @kshegunov said:

                  Also note that sending binary data over network when running on different platforms implies care for endianness and for the version of QDataStream.

                  I thought QDataStream took care of normalizing endianness. If I use the default value for the sender and all clients, I should be fine regardless of platform, correct? I understand about the versioning of the QDataStream.

                  Thanks for the link to your project. I will definitely be checking it out.

                  I think sending size information as part of the message header is the way to go. It's nearly impossible to use a single-character EOT for binary data, and using multi-character EOT sequence seems like overkill when a header can suffice

                  kshegunovK 1 Reply Last reply
                  0
                  • SGaistS SGaist

                    Hi,

                    Depending on your needs QtRemoteObjects might be of interest.

                    What about solutions like protobuf ?

                    D Offline
                    D Offline
                    DRoscoe
                    wrote on last edited by
                    #9

                    @SGaist Thanks! I will check it out!

                    1 Reply Last reply
                    0
                    • D DRoscoe

                      @kshegunov said:

                      Also note that sending binary data over network when running on different platforms implies care for endianness and for the version of QDataStream.

                      I thought QDataStream took care of normalizing endianness. If I use the default value for the sender and all clients, I should be fine regardless of platform, correct? I understand about the versioning of the QDataStream.

                      Thanks for the link to your project. I will definitely be checking it out.

                      I think sending size information as part of the message header is the way to go. It's nearly impossible to use a single-character EOT for binary data, and using multi-character EOT sequence seems like overkill when a header can suffice

                      kshegunovK Offline
                      kshegunovK Offline
                      kshegunov
                      Moderators
                      wrote on last edited by
                      #10

                      @DRoscoe

                      I thought QDataStream took care of normalizing endianness. If I use the default value for the sender and all clients, I should be fine regardless of platform, correct? I understand about the versioning of the QDataStream.

                      Hm, yes, I must have remembered wrong about the default setting. I thought it's platform dependent, but the docs clearly state it isn't. So you're absolutely fine not worrying about it.

                      I think sending size information as part of the message header is the way to go. It's nearly impossible to use a single-character EOT for binary data, and using multi-character EOT sequence seems like overkill when a header can suffice

                      I agree. Most of the time you don't need a full-fledged protocol and the hassle of implementing such thing for simple binary transfers is ... well, unwarranted. Plus it's not such a great improvement of using a protocol when you couple reception with parsing, and if you don't want to couple them, there's a whole new abstraction layer to be made ensuring the protocol is independent of the media ...

                      Kind regards.

                      Read and abide by the Qt Code of Conduct

                      1 Reply Last reply
                      0

                      • Login

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