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. Transferring data...
Forum Updated to NodeBB v4.3 + New Features

Transferring data...

Scheduled Pinned Locked Moved Unsolved General and Desktop
30 Posts 11 Posters 5.0k Views 4 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.
  • SPlattenS SPlatten

    I have been working on a C++ class to transfer a large amount of data to a clients, presently I'm working on the server and client being on the same system which is a 100MB/s network. The file is 1.17GB, what is the best way to transfer this data as presently it takes around 20 minutes to transfer.

    I've seen various online calculators which give 1 minute 45 seconds as the transfer time.

    https://techinternets.com/copy_calc

    I can't see how this can be.

    artwawA Offline
    artwawA Offline
    artwaw
    wrote on last edited by
    #2

    @SPlatten Those transfer rates are theoretical. You never get 100% through. For TCP/IP there is overhead coming from data encapsulation and data correction, network devices, the rest is depending on a way how you implement it and what exactly is your protocol doing. There might be also limitation coming from server side writing the data to the storage.

    I never implemented transfer routines for such amount of data but being a network engineer who does occasional development I'd lean towards the experiment where you write server and client part with variable data chunk size (I'd start, by the rule of thumb, with 64MB that can be upscaled/downscaled).

    Simple protocol where you use one connection in a loop, sending chunks. Server should write a chunk somewhere, then send single flag <done> meaning that it is ready for the next part. Experiment with chunk size and on the server side measure also how much time expires between receiving the chunk and safely storing it.

    That should give you some idea how the network performs in reality (each network might be slightly different when it comes to actual performance) and what the optimal sizes, caching, etc should be.

    As for actual implementation I'd see QDataStream for storing the data server side and tcp/ip sockets for the connection.

    Just a word of warning - might be that some of our more experienced colleagues here know better how to implement those, like I said - I never had to deal with large files.

    For more information please re-read.

    Kind Regards,
    Artur

    1 Reply Last reply
    2
    • SPlattenS Offline
      SPlattenS Offline
      SPlatten
      wrote on last edited by SPlatten
      #3

      @artwaw , thank you, I am using UDP as the protocol because of the larger packets it is capable of sending, however there is a two way transaction for every packet. In the system I've developed, the server sends a message to the clients, notifying them that a transfer is ready, this consists of a JSON packet:

      {"DSID"        : 1,                    /*Data Set ID */
       "RDF"         : "/folder/name.rdf",   /*Path and name of file to transfer*/
       "Filesize".   : 1234,                 /*File size in bytes*/
       "Totalblocks" : 1234}                 /*Number of blocks, where a block consists of N bytes */
      

      Each client will then start to issue requests for each block, where a block will contain N bytes of the file as stored in a database. Client request:

      {"DSID"     : 1,                    /*Data Set ID */
       "BlockNo"  : 0}                    /*Block number to request 0 to Totalblocks-1*/
      

      The server will respond to each request with:

      {"DSID"     : 1,                    /*Data Set ID */
       "BlockNo"  : 0}                    /*Block number to request 0 to Totalblocks-1*/
       "Checksum" : 0x1234,               /*Checksum of hex bytes for validation*/
       "Chunk".   : "hex bytes"}.        /*String containing hex nibbles*/
      

      The client requests each block until all blocks have been received. The client will also verify that the received data is correct by recalculating the checksum and comparing with the received checksum.

      This process isn't quick and takes typical around 20 minutes to transmit a GB file.

      Kind Regards,
      Sy

      jsulmJ C 2 Replies Last reply
      0
      • SPlattenS SPlatten

        @artwaw , thank you, I am using UDP as the protocol because of the larger packets it is capable of sending, however there is a two way transaction for every packet. In the system I've developed, the server sends a message to the clients, notifying them that a transfer is ready, this consists of a JSON packet:

        {"DSID"        : 1,                    /*Data Set ID */
         "RDF"         : "/folder/name.rdf",   /*Path and name of file to transfer*/
         "Filesize".   : 1234,                 /*File size in bytes*/
         "Totalblocks" : 1234}                 /*Number of blocks, where a block consists of N bytes */
        

        Each client will then start to issue requests for each block, where a block will contain N bytes of the file as stored in a database. Client request:

        {"DSID"     : 1,                    /*Data Set ID */
         "BlockNo"  : 0}                    /*Block number to request 0 to Totalblocks-1*/
        

        The server will respond to each request with:

        {"DSID"     : 1,                    /*Data Set ID */
         "BlockNo"  : 0}                    /*Block number to request 0 to Totalblocks-1*/
         "Checksum" : 0x1234,               /*Checksum of hex bytes for validation*/
         "Chunk".   : "hex bytes"}.        /*String containing hex nibbles*/
        

        The client requests each block until all blocks have been received. The client will also verify that the received data is correct by recalculating the checksum and comparing with the received checksum.

        This process isn't quick and takes typical around 20 minutes to transmit a GB file.

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

        @SPlatten said in Transferring data...:

        This process isn't quick and takes typical around 20 minutes to transmit a GB file.

        And how long does it take if you use TCP instead of "simulating" TCP with your own implementation?

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

        SPlattenS 1 Reply Last reply
        2
        • jsulmJ jsulm

          @SPlatten said in Transferring data...:

          This process isn't quick and takes typical around 20 minutes to transmit a GB file.

          And how long does it take if you use TCP instead of "simulating" TCP with your own implementation?

          SPlattenS Offline
          SPlattenS Offline
          SPlatten
          wrote on last edited by
          #5

          @jsulm , since TCP packets are limited to 1.5K I can only assume it will take significantly longer.

          Kind Regards,
          Sy

          jsulmJ 1 Reply Last reply
          0
          • SPlattenS SPlatten

            @jsulm , since TCP packets are limited to 1.5K I can only assume it will take significantly longer.

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

            @SPlatten said in Transferring data...:

            I can only assume it will take significantly longer

            That's my point - you are assuming, you actually do not know.

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

            SPlattenS 1 Reply Last reply
            1
            • jsulmJ jsulm

              @SPlatten said in Transferring data...:

              I can only assume it will take significantly longer

              That's my point - you are assuming, you actually do not know.

              SPlattenS Offline
              SPlattenS Offline
              SPlatten
              wrote on last edited by
              #7

              @jsulm , all I can go on is the data thats in front of me. TCP packets can send 1.5K, UDP packets can send 64K, what isn't clear?

              Kind Regards,
              Sy

              JonBJ jeremy_kJ 2 Replies Last reply
              0
              • SPlattenS SPlatten

                @jsulm , all I can go on is the data thats in front of me. TCP packets can send 1.5K, UDP packets can send 64K, what isn't clear?

                JonBJ Offline
                JonBJ Offline
                JonB
                wrote on last edited by JonB
                #8

                @SPlatten
                What is not clear is:

                • How do you know sending 64K packets actually transfers at ~40 x the speed of 1.5K packets?

                • How do you know given your own protocol which "simulates" TCP packet transfer reliability what overhead that places on your assumed timings?

                We have said before it is not clear that UDP will be superior to TCP for reliable transfer. Maybe it is, maybe it isn't. All people are saying is why not take the time to find out for yourself how it compares instead of stating it will be more efficient? It's up to you.

                SPlattenS 1 Reply Last reply
                2
                • JonBJ JonB

                  @SPlatten
                  What is not clear is:

                  • How do you know sending 64K packets actually transfers at ~40 x the speed of 1.5K packets?

                  • How do you know given your own protocol which "simulates" TCP packet transfer reliability what overhead that places on your assumed timings?

                  We have said before it is not clear that UDP will be superior to TCP for reliable transfer. Maybe it is, maybe it isn't. All people are saying is why not take the time to find out for yourself how it compares instead of stating it will be more efficient? It's up to you.

                  SPlattenS Offline
                  SPlattenS Offline
                  SPlatten
                  wrote on last edited by
                  #9

                  @JonB , thank you, I will try. I'm using Sockets, is there a built in tried and tested method of transferring files over TCP that I can try?

                  Because without this I would implement the same protocol I've adopted for UDP but using TCP sockets.

                  Kind Regards,
                  Sy

                  JonBJ artwawA 2 Replies Last reply
                  0
                  • SPlattenS SPlatten

                    @JonB , thank you, I will try. I'm using Sockets, is there a built in tried and tested method of transferring files over TCP that I can try?

                    Because without this I would implement the same protocol I've adopted for UDP but using TCP sockets.

                    JonBJ Offline
                    JonBJ Offline
                    JonB
                    wrote on last edited by JonB
                    #10

                    @SPlatten said in Transferring data...:

                    I would implement the same protocol I've adopted for UDP but using TCP sockets

                    Well I don't think so because you spend time explaining you do chunks, checksums, retries and re-ordering. You wouldn't do any of that with TCP, would you? So presumably your code will be simpler.

                    I think when I have done this before I just did protocol of: client requests file, sender sends back leading long of total file size, then client reads till that many bytes received. I'm not sure whether an alternative could be to send a "0-packet-size" message as terminator. There will be stuff out there for this, even particularly for Qt.

                    I'm not as expert over UDP as others. What about: put the simplest TCP alternative in place. Time it (a few times) for one client to one server. Then time it for two clients, and half a dozen clients. Then see where you are so far?

                    As I said before: maybe you are right about efficiency, especially for multiple clients, I don't know. I just have a nagging feeling that with your retries etc. you are duplicating what TCP would do for you, and if this was so much better why haven't I heard about this UDP approach as a "thing" for multiple transfer?

                    You may be right in one situation. Not my area (I am strictly legal!), but how do these "torrent" streamer things work? I believe they download & upload files to/from your client, like in "batches" over time. Maybe that does simulate "efficiently distributing big files to/from many clients", does it use UDP, I don't know. Then again, I think they certainly are not about speed, more maybe about reducing total network traffic? UPDATE @jsulm has looked it up, and they use TCP, just multiple connections (between client and server for one file) and small packets. That might give you some food for thought... :)

                    1 Reply Last reply
                    2
                    • SPlattenS SPlatten

                      @JonB , thank you, I will try. I'm using Sockets, is there a built in tried and tested method of transferring files over TCP that I can try?

                      Because without this I would implement the same protocol I've adopted for UDP but using TCP sockets.

                      artwawA Offline
                      artwawA Offline
                      artwaw
                      wrote on last edited by artwaw
                      #11

                      @SPlatten Do not use UDP for transferring the data that can't be lost! @JonB is very right about you simulating TCP/IP control flow, don't do that. You will not get better results than using plain TCP/IP. While frame size of TCP/IP is smaller, it might actually be faster. The test I mentioned above, I'd see it using QTcpSocket with minimum control flow connected to signals of like connected(), stateChanged() and errorOccured(), plus monitoring (maybe) bytesToWrite() on the sending part and bytesAvailable() on the receiving end.

                      With the socket and QDataStream you can actually use << operators - and that's where the size of the data chunk I mentioned above comes in, you can actually output timings from QElapsedTimer on both ends to find the bottlenecks. Don't go into to deep level of implementation since that's where usually the unnecessary complications occur. Please try to use the highest implementation level possible and allow Qt to do its parts.

                      Socket documentation (I know that you've read it already but just allow me to hang in here my reference point for clarity of the post): https://doc.qt.io/qt-5/qabstractsocket.html

                      Word on recalculating the CRC - I would not calculate those for the parts, since TCP/IP makes sure that for any given continuous transfer CRC of the parts/frames is sound and that the parts are ordered correctly. Calculate it once at the very end, once you've got the whole file.

                      For more information please re-read.

                      Kind Regards,
                      Artur

                      1 Reply Last reply
                      2
                      • AxelViennaA Offline
                        AxelViennaA Offline
                        AxelVienna
                        wrote on last edited by AxelVienna
                        #12

                        @SPlatten
                        Putting aside the TCP / UDP discussion for a minute, the simplicity-driven speed of UDP is basically limited by your physical environment. The copy_calc speed is based on the assumption that the given bandwidth is fully available between your traffic endpoints. USB traffic (w/o USB HUBs!) is the only use case where this assumption always holds true. You are sending UDP broad- or multicasts across your network. The first bottle neck is your server's ethernet adapter. Your max outbound speed is the server's adapter speed / number of clients. Next bottle neck is your router/hub/switch, which comes with a number of different potential factors which will slow down your traffic:

                        (1) Physical limitations
                        Depending how new and fast your router/hub/switch is

                        (2) Configuration
                        Protocols, ports and endpoints may or may not be prioritized.
                        Every package must be inspected to determine its priority.
                        So even if your UDP traffic enjoys top priority, the inspection itself slows it down.

                        (3) Logical factors
                        How connections are rendered between two endpoints largely depends on internal algorithms in your router/hub/switch hardware. Some switches have UDP optimizers which accept basically a package and send it to all multi-/broadcast addresses at the same time. Others buffer and serialize.
                        The speed of optimized UDP fully unfolds only if it is truly unidirectional. Since your environment works with bi-directional features (basically a limited TCP re-implementation), this may slow down your hardware performance additionally. Since UDP optimizers take the risk of package loss for the sake of speed, your hardware configuration may be a trigger for your bi-directional features so you end up in a vicious circle: UDP-optimization => package loss => bi-directional features => more package loss => more bi-directional features etc.

                        Having said that: While your case is certainly interesting, I am not surprised that you don't get the speed you want. Debugging your bi-directional features (e.g. requests to resend missing packages) will give you an idea where the troublemaker is to be located. Your hardware is most likely punishing you for using TCP like features on UDP. Moreover, you loose TCP based optimization features which your hardware may even provide.

                        This is probably not the solution you expected, however, I hope it sheds some light on the matter.

                        C++ and Python walk into a bar. C++ reuses the first glass.

                        SPlattenS 1 Reply Last reply
                        2
                        • AxelViennaA AxelVienna

                          @SPlatten
                          Putting aside the TCP / UDP discussion for a minute, the simplicity-driven speed of UDP is basically limited by your physical environment. The copy_calc speed is based on the assumption that the given bandwidth is fully available between your traffic endpoints. USB traffic (w/o USB HUBs!) is the only use case where this assumption always holds true. You are sending UDP broad- or multicasts across your network. The first bottle neck is your server's ethernet adapter. Your max outbound speed is the server's adapter speed / number of clients. Next bottle neck is your router/hub/switch, which comes with a number of different potential factors which will slow down your traffic:

                          (1) Physical limitations
                          Depending how new and fast your router/hub/switch is

                          (2) Configuration
                          Protocols, ports and endpoints may or may not be prioritized.
                          Every package must be inspected to determine its priority.
                          So even if your UDP traffic enjoys top priority, the inspection itself slows it down.

                          (3) Logical factors
                          How connections are rendered between two endpoints largely depends on internal algorithms in your router/hub/switch hardware. Some switches have UDP optimizers which accept basically a package and send it to all multi-/broadcast addresses at the same time. Others buffer and serialize.
                          The speed of optimized UDP fully unfolds only if it is truly unidirectional. Since your environment works with bi-directional features (basically a limited TCP re-implementation), this may slow down your hardware performance additionally. Since UDP optimizers take the risk of package loss for the sake of speed, your hardware configuration may be a trigger for your bi-directional features so you end up in a vicious circle: UDP-optimization => package loss => bi-directional features => more package loss => more bi-directional features etc.

                          Having said that: While your case is certainly interesting, I am not surprised that you don't get the speed you want. Debugging your bi-directional features (e.g. requests to resend missing packages) will give you an idea where the troublemaker is to be located. Your hardware is most likely punishing you for using TCP like features on UDP. Moreover, you loose TCP based optimization features which your hardware may even provide.

                          This is probably not the solution you expected, however, I hope it sheds some light on the matter.

                          SPlattenS Offline
                          SPlattenS Offline
                          SPlatten
                          wrote on last edited by
                          #13

                          @AxelVienna , thank you, I'm developing on a supplied laptop where presently the client and server are on the same system, this isn't how it will be when rolled out.

                          Kind Regards,
                          Sy

                          JonBJ AxelViennaA 2 Replies Last reply
                          0
                          • SPlattenS SPlatten

                            @AxelVienna , thank you, I'm developing on a supplied laptop where presently the client and server are on the same system, this isn't how it will be when rolled out.

                            JonBJ Offline
                            JonBJ Offline
                            JonB
                            wrote on last edited by
                            #14

                            @SPlatten said in Transferring data...:

                            this isn't how it will be when rolled out.

                            I was going to ask about this earlier. One trouble I foresee is how you will know how your approach fares in another environment, particularly about required retries. With TCP you may not know the speed but you do know it will be reliable. With your UDP I don't know how you can anticipate its performance in a distributed environment.

                            SPlattenS 1 Reply Last reply
                            0
                            • JonBJ JonB

                              @SPlatten said in Transferring data...:

                              this isn't how it will be when rolled out.

                              I was going to ask about this earlier. One trouble I foresee is how you will know how your approach fares in another environment, particularly about required retries. With TCP you may not know the speed but you do know it will be reliable. With your UDP I don't know how you can anticipate its performance in a distributed environment.

                              SPlattenS Offline
                              SPlattenS Offline
                              SPlatten
                              wrote on last edited by
                              #15

                              @JonB , I'm going to look into using QTCP now, is there any good quick start example I can look at or is it simply write the data to the Socket ?

                              Kind Regards,
                              Sy

                              artwawA JonBJ 2 Replies Last reply
                              0
                              • SPlattenS SPlatten

                                @JonB , I'm going to look into using QTCP now, is there any good quick start example I can look at or is it simply write the data to the Socket ?

                                artwawA Offline
                                artwawA Offline
                                artwaw
                                wrote on last edited by
                                #16

                                @SPlatten From the documentation I posted above:

                                https://doc.qt.io/qt-5/qtnetwork-fortuneclient-example.html

                                https://doc.qt.io/qt-5/qtnetwork-blockingfortuneclient-example.html

                                For more information please re-read.

                                Kind Regards,
                                Artur

                                SPlattenS 1 Reply Last reply
                                1
                                • SPlattenS SPlatten

                                  @JonB , I'm going to look into using QTCP now, is there any good quick start example I can look at or is it simply write the data to the Socket ?

                                  JonBJ Offline
                                  JonBJ Offline
                                  JonB
                                  wrote on last edited by
                                  #17

                                  @SPlatten
                                  In addition to @artwaw, Googling qtcpsocket file transfer example gives quite a lot to look through.

                                  SPlattenS 1 Reply Last reply
                                  1
                                  • artwawA artwaw

                                    @SPlatten From the documentation I posted above:

                                    https://doc.qt.io/qt-5/qtnetwork-fortuneclient-example.html

                                    https://doc.qt.io/qt-5/qtnetwork-blockingfortuneclient-example.html

                                    SPlattenS Offline
                                    SPlattenS Offline
                                    SPlatten
                                    wrote on last edited by
                                    #18

                                    @artwaw thank you

                                    Kind Regards,
                                    Sy

                                    1 Reply Last reply
                                    0
                                    • JonBJ JonB

                                      @SPlatten
                                      In addition to @artwaw, Googling qtcpsocket file transfer example gives quite a lot to look through.

                                      SPlattenS Offline
                                      SPlattenS Offline
                                      SPlatten
                                      wrote on last edited by
                                      #19

                                      @JonB, thank you

                                      Kind Regards,
                                      Sy

                                      1 Reply Last reply
                                      0
                                      • SPlattenS SPlatten

                                        @AxelVienna , thank you, I'm developing on a supplied laptop where presently the client and server are on the same system, this isn't how it will be when rolled out.

                                        AxelViennaA Offline
                                        AxelViennaA Offline
                                        AxelVienna
                                        wrote on last edited by
                                        #20

                                        @SPlatten said in Transferring data...:

                                        @AxelVienna , thank you, I'm developing on a supplied laptop where presently the client and server are on the same system, this isn't how it will be when rolled out.

                                        With client and server hosted on the same machine, the vicious circle I described is still likely to happen: Blocking code or performance issues on the client side, will cause package loss.

                                        C++ and Python walk into a bar. C++ reuses the first glass.

                                        1 Reply Last reply
                                        0
                                        • SPlattenS SPlatten

                                          I have been working on a C++ class to transfer a large amount of data to a clients, presently I'm working on the server and client being on the same system which is a 100MB/s network. The file is 1.17GB, what is the best way to transfer this data as presently it takes around 20 minutes to transfer.

                                          I've seen various online calculators which give 1 minute 45 seconds as the transfer time.

                                          https://techinternets.com/copy_calc

                                          I can't see how this can be.

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

                                          @SPlatten said in Transferring data...:

                                          presently it takes around 20 minutes to transfer.

                                          Your implementation must be rather dubious, I'd say. A 10/100 network (the typical cat5(e) UTP without much noise on the channel) will easily give you ~10 MB/s transfer speed (in reality, not theoretical) over plain TCP, which should sum up to just about under 2 minutes.

                                          Read and abide by the Qt Code of Conduct

                                          Pablo J. RoginaP 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