Results 1 to 5 of 5

Thread: QTcpSocket - making sure all data was sent

  1. #1
    Join Date
    Jul 2011
    Posts
    4
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Question QTcpSocket - making sure all data was sent

    I'm integrating socket comms into a dialog, and have a question about ensuring that all data was sent when using QTcpSocket::write. My approach to this is the following:

    1. When meaning to send (say, a QByteArray), call QTcpSocket::write
    2. Connect a slot to the bytesWritten signal, where I increment an internal counter with the amount of bytes sent so far, and if bytesToWrite() == 0, more data needs to be sent
    3. When sending "more data", use the counter to index into the buffer to send the rest of it.
    4. The previous two steps will be invoked over and over until all data is sent.


    Is this the correct way of ensuring the whole buffer gets sent eventually? Is there an easier way?

    Thanks in advance

  2. #2
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: QTcpSocket - making sure all data was sent

    Unless the connection is abnormally or deliberately terminated all the bytes written will be sent. Qt and your operating system TCP stack looks after things like queuing, window sizes, ensuring "optimal" pipelines, and ensuring that bytes are received intact.

  3. #3
    Join Date
    Jul 2011
    Posts
    4
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QTcpSocket - making sure all data was sent

    ChrisW67 - thanks for your reply,

    However, I know it is good practice in most languages (including the lowest-level 'send' function from the socket C API) to check this return value (for non-blocking calls). The manual page of 'send' says that a partial write may be returned if the message doesn't fit into the send buffer. This can happen if the network is congested for some reason, or the receiving side doesn't ack fast enough.

    Do you intend to imply this *never* really happens?

  4. #4
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: QTcpSocket - making sure all data was sent

    Every byte that a QIODevice/QTCPSocket accepts for sending will be sent barring abnormal termination. That is not to say that every byte offered will be accepted for sending, i.e. QIODevice::write() may return a positive number smaller than the number of bytes offered. You have to handle that if it is likely to apply. I've never seen it myself, but I only send short messages generally.

    I read your initial question as if you were trying to coopt the TCP windowing mechanisms. I think waiting until all the bytes accepted have been sent before offering more bytes is sub-optimal. You are waiting for an empty buffer rather than trying to keep the send buffer near-full. By keeping the send buffer near-full you ensure that Qt and OS can operate normally with respect to the throughput regulation mechanisms in TCP. You might like to add more data to the queue every time bytesSent() is received, or only after x KB are sent (an adaptation of your original suggestion).

  5. #5
    Join Date
    Jul 2011
    Posts
    4
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QTcpSocket - making sure all data was sent

    Quote Originally Posted by ChrisW67 View Post
    Every byte that a QIODevice/QTCPSocket accepts for sending will be sent barring abnormal termination. That is not to say that every byte offered will be accepted for sending, i.e. QIODevice::write() may return a positive number smaller than the number of bytes offered. You have to handle that if it is likely to apply. I've never seen it myself, but I only send short messages generally.

    I read your initial question as if you were trying to coopt the TCP windowing mechanisms. I think waiting until all the bytes accepted have been sent before offering more bytes is sub-optimal. You are waiting for an empty buffer rather than trying to keep the send buffer near-full. By keeping the send buffer near-full you ensure that Qt and OS can operate normally with respect to the throughput regulation mechanisms in TCP. You might like to add more data to the queue every time bytesSent() is received, or only after x KB are sent (an adaptation of your original suggestion).
    The thing is, I also have just relatively short packages to send. But I want to be 100% sure they are actually sent, so the two options are either what I originally wrote, or loop on ::write until it reports all send. The latter doesn't play with the GUI event loop well.

    Perhaps my approach is an overkill, but it will only be triggered in very rare cases so maybe that's not too bad?

Similar Threads

  1. QTcpSocket Writing Data Progress
    By lwinhtooko in forum Qt Programming
    Replies: 2
    Last Post: 1st November 2010, 20:10
  2. QTCPsocket data corrupt when receive
    By gabizzz in forum Qt Programming
    Replies: 2
    Last Post: 4th March 2010, 17:29
  3. QTCPSocket not getting all data
    By jhowland in forum Qt Programming
    Replies: 4
    Last Post: 29th January 2010, 15:20
  4. QTcpSocket + receiving data
    By navi1084 in forum Qt Programming
    Replies: 1
    Last Post: 2nd June 2009, 08:10
  5. Problem with reading in data from a QTCPSocket
    By Denarius in forum Qt Programming
    Replies: 4
    Last Post: 24th April 2009, 08:54

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.