Results 1 to 9 of 9

Thread: Problems with maximum data sent over a QTcpSocket

  1. #1
    Join Date
    Feb 2010
    Posts
    3
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Problems with maximum data sent over a QTcpSocket

    Hi, I am trying to create a basic videoconference program for an university assignment.
    I am using Qt 4.5.2 on Linux.

    When I send full images (something like 230k) over the socket it waits in the socket.disconnect() on the sender side and on the receiver side it only goes to 170k or so of bytesAvailable().

    I am sending images through QTcpSocket like this:

    Sender's side:

    Qt Code:
    1. int NetworkSender::sendData (char *image, int dataSize, unsigned short port)
    2. {
    3. QTcpSocket socket;
    4. int return_value;
    5.  
    6. socket.connectToHost(remoteHost, port);
    7.  
    8. QByteArray block;
    9. QDataStream out(&block, QIODevice::WriteOnly);
    10. out.setVersion(QDataStream::Qt_4_0);
    11. out << (quint32)0;
    12. out.writeBytes((const char*)image, dataSize);
    13. out.device()->seek(0);
    14. out << (quint32)(block.size() - sizeof(quint32));
    15.  
    16. return_value = socket.write(block);
    17. //socket.flush();
    18. //socket.waitForBytesWritten(20);
    19.  
    20. socket.disconnectFromHost();
    21. socket.waitForDisconnected();
    22.  
    23. if (return_value != -1) {
    24.  
    25. return 0;
    26. }else {
    27. return -1;
    28. }
    29. }
    To copy to clipboard, switch view to plain text mode 


    On the receiver side I have a thread, like this:


    Qt Code:
    1. void NetworkReceiverThread::run()
    2. {
    3. QTcpSocket socket;
    4. // socket.setReadBufferSize(500000);
    5.  
    6. int timeout = 2 * 1000;
    7.  
    8. if (!socket.setSocketDescriptor(socketDescriptor)) {
    9. emit error(socket.error(), socket.errorString());
    10. return;
    11. }
    12.  
    13. while (socket.bytesAvailable() < (int)sizeof(quint32)) {
    14. if (!socket.waitForReadyRead(timeout)) {
    15. emit error(socket.error(), socket.errorString());
    16. return;
    17. }
    18. }
    19.  
    20. quint32 blockSize;
    21. QDataStream in(&socket);
    22. in.setVersion(QDataStream::Qt_4_0);
    23. in >> blockSize;
    24. while (socket.bytesAvailable() < blockSize) {
    25. if (!socket.waitForReadyRead(timeout)) {
    26. qDebug("4");
    27. emit error(socket.error(), socket.errorString());
    28. return;
    29. }
    30. }
    31. qDebug("5");
    32.  
    33. unsigned int data_len;
    34. in.readBytes(data, data_len);
    35.  
    36. qDebug("received data");
    37. qDebug(QString::number(data_len).toStdString().data());
    38.  
    39. emit(done());
    40. }
    To copy to clipboard, switch view to plain text mode 


    As I said if I try to put a debug on the reader inside " while (socket.bytesAvailable() < blockSize) {" printing bytes available I got something like 80k , 120k 160k and then it stops.
    I have tried to set manually the buffer of the receiver as can be seen as a commented line, same result.
    I have tried also calling flush() on the sender just after the write(), I got this:

    QNativeSocketEngine::write() was not called in QAbstractSocket::ConnectedState
    QAbstractSocket::waitForDisconnected() is not allowed in UnconnectedState
    I have tried waitForBytesWritten() but same result

    I am testing on loopback (127.0.0.1)
    Last edited by jordip; 3rd February 2010 at 12:04.

  2. #2
    Join Date
    Jan 2006
    Location
    Sta. Eugènia de Berga (Vic - Barcelona - Spain)
    Posts
    869
    Thanks
    70
    Thanked 59 Times in 57 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Problems with maximum data sent over a QTcpSocket

    Hi,

    If you want to use Threads into reciver application with a socket call "exec()" instead and connect the SIGNAL "readyRead" from the socket to your slot.
    Òscar Llarch i Galán

  3. #3
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,714
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: Problems with maximum data sent over a QTcpSocket

    Don't wait until you have enough bytes available to read, rather, read all the bytes that are available, and count them, and stop reading when you got all the bytes you need.
    The problem is, that it might be that the bytes you are expecting are more then the internal socket buffer size, in which case, you will never get enough bytes on bytesAvailable().
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

  4. #4
    Join Date
    Jan 2008
    Location
    Poland
    Posts
    687
    Thanks
    4
    Thanked 140 Times in 132 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Problems with maximum data sent over a QTcpSocket

    The problem you faced is a normal socket behavior. Notice that QIODevice::write() also returna how many byte were actually written. When receiving you need to read as many byte as it arrives, store it in some buffer and repeat it until you have all required data in your buffer.
    I would like to be a "Guru"

    Useful hints (try them before asking):
    1. Use Qt Assistant
    2. Search the forum

    If you haven't found solution yet then create new topic with smart question.

  5. #5
    Join Date
    Feb 2010
    Posts
    3
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Problems with maximum data sent over a QTcpSocket

    Thanks for you input!
    I have changed the code, now I read as there are bytes available instead of waiting for the whole thing to come, anyway it is still not working ;(
    Also, I am sure that the data + position pointer mangling can be done much better ...

    Qt Code:
    1. char *data;
    2. uint data_len = 0;
    3.  
    4. quint32 blockSize;
    5. QDataStream in(&socket);
    6. unsigned int position = 0;
    7.  
    8. in.setVersion(QDataStream::Qt_4_5);
    9. in >> blockSize;
    10.  
    11. data = new char[blockSize];
    12.  
    13. while (position < blockSize) {
    14. in.readRawData (data + position, data_len);
    15. blockSize -= data_len;
    16. position += data_len;
    17. qDebug(QString ("pos: " + QString::number(position) + " " + QString::number(data_len)).toStdString().data());
    18. if (blockSize > 0) {
    19. if (!socket.waitForReadyRead(timeout)) {
    20. qDebug("4");
    21. emit error(socket.error(), socket.errorString());
    22. return;
    23. }
    24. }
    25. }
    To copy to clipboard, switch view to plain text mode 

    The very clumsy qDebug up there prints position 0 in each iteration of the loop, so, something should be wrong with the sender, I guess.

    This is my sender:

    Qt Code:
    1. //socket.connectToHost(remoteHost, port);
    2. socket.connectToHost("127.0.0.1", port);
    3. /*
    4.   if ( socket.state() != QAbstractSocket::ConnectedState )
    5. {
    6. qDebug(socket.errorString().toStdString().data());
    7. return -1;
    8. }
    9. */
    10. QByteArray block;
    11. QDataStream out(&block, QIODevice::WriteOnly);
    12. out.setVersion(QDataStream::Qt_4_5);
    13.  
    14. out << (quint32)0;
    15. out.writeBytes((const char*)image, dataSize);
    16. out.device()->seek(0);
    17. out << (quint32)(block.size() - sizeof(quint32));
    18.  
    19. int bytes_written = 0;
    20. int bytes_to_write = block.size();
    21.  
    22. while (bytes_written < bytes_to_write)
    23. {
    24. written = socket.write(block);
    25. socket.flush();
    26. bytes_written += written;
    27.  
    28. qDebug(QString ("write: " + QString::number(written) + " " + QString::number(bytes_to_write)).toStdString().data());
    29.  
    30. socket.waitForBytesWritten(20);
    31. }
    To copy to clipboard, switch view to plain text mode 

    The qDebug shows that I am writing the datastream in only one call and I get stuck waiting.

    If I uncomment the check for the connection status, I can see I am not connected and I errorString is unknown error If I run netstat then, I can see a lot of TIME_WAIT connections on that port.
    In the case I send a minimun amount of data seems to connect thought

    I am quite clueless at this point
    Last edited by jordip; 5th February 2010 at 12:32.

  6. #6
    Join Date
    Jan 2008
    Location
    Poland
    Posts
    687
    Thanks
    4
    Thanked 140 Times in 132 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Problems with maximum data sent over a QTcpSocket

    you have set data_len to 0 and never update it so you always let your stream to read 0 bytes. Use QAbstractSocket::bytesAvailable() to get available bytes count.
    I would like to be a "Guru"

    Useful hints (try them before asking):
    1. Use Qt Assistant
    2. Search the forum

    If you haven't found solution yet then create new topic with smart question.

  7. #7
    Join Date
    Oct 2009
    Posts
    37
    Thanked 4 Times in 4 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11

    Default Re: Problems with maximum data sent over a QTcpSocket

    I'd not use the waitFor functions.
    Connect slots to the readyRead() signal of the socket and do the reading there.
    Disclaimer: Although I work on Qt for Nokia, anything I post here is personal

  8. #8
    Join Date
    Apr 2010
    Posts
    1
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Problems with maximum data sent over a QTcpSocket

    hi, may be you need to wait for connected before calling socket.write()

    try add
    socket.waitForConnected(); between the line socket.connectToHost() and socket.write(block)

    I encountered this problem also, and the unknown error was fixed after adding it.

  9. #9
    Join Date
    Apr 2010
    Posts
    13
    Qt products
    Qt3 Qt4 Qt/Embedded

    Default Re: Problems with maximum data sent over a QTcpSocket

    Hello , one question , when the following code is executed , what is the value of socketDescriptor or how do you obtain the value of socketDescriptor


    if (!socket.setSocketDescriptor(socketDescriptor)) {
    emit error(socket.error(), socket.errorString());
    return;
    }





    Quote Originally Posted by jordip View Post
    Hi, I am trying to create a basic videoconference program for an university assignment.
    I am using Qt 4.5.2 on Linux.

    When I send full images (something like 230k) over the socket it waits in the socket.disconnect() on the sender side and on the receiver side it only goes to 170k or so of bytesAvailable().

    I am sending images through QTcpSocket like this:

    Sender's side:

    Qt Code:
    1. int NetworkSender::sendData (char *image, int dataSize, unsigned short port)
    2. {
    3. QTcpSocket socket;
    4. int return_value;
    5.  
    6. socket.connectToHost(remoteHost, port);
    7.  
    8. QByteArray block;
    9. QDataStream out(&block, QIODevice::WriteOnly);
    10. out.setVersion(QDataStream::Qt_4_0);
    11. out << (quint32)0;
    12. out.writeBytes((const char*)image, dataSize);
    13. out.device()->seek(0);
    14. out << (quint32)(block.size() - sizeof(quint32));
    15.  
    16. return_value = socket.write(block);
    17. //socket.flush();
    18. //socket.waitForBytesWritten(20);
    19.  
    20. socket.disconnectFromHost();
    21. socket.waitForDisconnected();
    22.  
    23. if (return_value != -1) {
    24.  
    25. return 0;
    26. }else {
    27. return -1;
    28. }
    29. }
    To copy to clipboard, switch view to plain text mode 


    On the receiver side I have a thread, like this:


    Qt Code:
    1. void NetworkReceiverThread::run()
    2. {
    3. QTcpSocket socket;
    4. // socket.setReadBufferSize(500000);
    5.  
    6. int timeout = 2 * 1000;
    7.  
    8. if (!socket.setSocketDescriptor(socketDescriptor)) {
    9. emit error(socket.error(), socket.errorString());
    10. return;
    11. }
    12.  
    13. while (socket.bytesAvailable() < (int)sizeof(quint32)) {
    14. if (!socket.waitForReadyRead(timeout)) {
    15. emit error(socket.error(), socket.errorString());
    16. return;
    17. }
    18. }
    19.  
    20. quint32 blockSize;
    21. QDataStream in(&socket);
    22. in.setVersion(QDataStream::Qt_4_0);
    23. in >> blockSize;
    24. while (socket.bytesAvailable() < blockSize) {
    25. if (!socket.waitForReadyRead(timeout)) {
    26. qDebug("4");
    27. emit error(socket.error(), socket.errorString());
    28. return;
    29. }
    30. }
    31. qDebug("5");
    32.  
    33. unsigned int data_len;
    34. in.readBytes(data, data_len);
    35.  
    36. qDebug("received data");
    37. qDebug(QString::number(data_len).toStdString().data());
    38.  
    39. emit(done());
    40. }
    To copy to clipboard, switch view to plain text mode 


    As I said if I try to put a debug on the reader inside " while (socket.bytesAvailable() < blockSize) {" printing bytes available I got something like 80k , 120k 160k and then it stops.
    I have tried to set manually the buffer of the receiver as can be seen as a commented line, same result.
    I have tried also calling flush() on the sender just after the write(), I got this:


    I have tried waitForBytesWritten() but same result

    I am testing on loopback (127.0.0.1)

Similar Threads

  1. QTCPSocket not getting all data
    By jhowland in forum Qt Programming
    Replies: 4
    Last Post: 29th January 2010, 15:20
  2. QTcpSocket + receiving data
    By navi1084 in forum Qt Programming
    Replies: 1
    Last Post: 2nd June 2009, 08:10
  3. Problem with reading in data from a QTCPSocket
    By Denarius in forum Qt Programming
    Replies: 4
    Last Post: 24th April 2009, 08:54
  4. Problem in printing the data return /read from QTcpsocket
    By skumar434 in forum Qt Programming
    Replies: 3
    Last Post: 20th February 2009, 19:36
  5. Problems with QThread and QTcpSocket
    By cookiem in forum Qt Programming
    Replies: 6
    Last Post: 2nd November 2006, 08:25

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.