Before describing my problem, let me first give you the background of my application. There is a tcp server (which is written in Delpi) and a tcp client which I am writing in C++ (Qt). When the client connects to the server, the server sends a large chunk of configuration data to the client (about 3 MB). The problem I am having is that the TCP connection is being disconnected during the receive of this large chunk of data.

I've tried (temporarily) reducing the data size down to a few hundred Kbytes, and sometimes it works, sometimes it fails. It seems to fail more regularly with slower PCs. If I reduce it to 10KB, it works 100% of the time, but I need to be able to have it work with the 3MB of data the host will normally send. I have also experimented with having the host wait for a minute before sending the large chunk of data, and send little chunks first. The smaller chunks (a few KB) work fine, but the disconnect still happens when the large chunk comes in. Also, the number of bytes received before the connection is broken seems to vary randomly.

The server is (currently) running on the same machine, and we are using the loopback address (127.0.0.1) as the connection IP address.

The following is the slot which signaled when data is received:

Qt Code:
  1. void Socket::dataReadyToRead()
  2. {
  3. /*
  4. * Let us lock this slot so that further hitting on this cause wait while it is
  5. * already hitted.
  6. */
  7. QMutexLocker locker(&mMutex);
  8.  
  9. /*
  10. * We will only read data when at least one command is arrived. Here is the logic...
  11. * We will continue till the length of the next command is arrived. If only length is
  12. * arrived (not content yet), just read it in d->mnBlockSize (NOTE: LSB come first, i.e, little endian),
  13. * leave this method. But if content arrived too, let us read it and process this command.
  14. */
  15. while(bytesAvailable() >= (int)sizeof(quint32)){
  16. if (0 == mnBlockSize){
  17. /*
  18. * Read the length bytes first. And as LSB come first, need to calc length like following.
  19. */
  20. char length_byte[4];
  21. read(length_byte,4);
  22.  
  23. mnBlockSize = length_byte[0];
  24. mnBlockSize += (length_byte[1] * 256);
  25. mnBlockSize += (length_byte[2] * 256 * 256);
  26. mnBlockSize += (length_byte[3] * 256 * 256 * 256);
  27. }
  28.  
  29. /*
  30. * Content is not available yet, so there is nothing to do.
  31. */
  32. if (bytesAvailable() < mnBlockSize){
  33. return;
  34. }
  35.  
  36. /*
  37. * Content arrived, so get it, copy it to a buffer, analyze the packet by calling
  38. * prepareCommand and them emit the prepared packet to the system so that
  39. * contorller get it and process it.
  40. */
  41. char dataArrived[MAX_DATA_LENGTH];
  42. read(dataArrived,mnBlockSize);
  43.  
  44. if(mnBlockSize <= MAX_DATA_LENGTH){
  45. QByteArray com(dataArrived,mnBlockSize);
  46. emit commandCame(com);
  47. }
  48.  
  49. mnBlockSize = 0;
  50. }
  51. }
To copy to clipboard, switch view to plain text mode 

Following is the thread run method’s code.
Qt Code:
  1. void SocketThread::run()
  2. {
  3. if(mTcpHandler){
  4. Socket tcpClient;
  5. connect(mTcpHandler, SIGNAL(connectToBobHost(QString, int)), &tcpClient, SLOT(connectToBobHost(QString, int)));
  6. connect(mTcpHandler, SIGNAL(disconnectFromBobHost()), &tcpClient, SLOT(disconnectFromBobHost()), Qt::BlockingQueuedConnection);
  7. connect(mTcpHandler, SIGNAL(dataReadyToSend(QByteArray)), &tcpClient, SLOT(sendData(QByteArray)));
  8.  
  9. connect(&tcpClient, SIGNAL(hostConnected()), mTcpHandler, SLOT(hostConnected()));
  10. connect(&tcpClient, SIGNAL(hostDisconnected(bool )), mTcpHandler, SLOT(hostDisconnected(bool)), Qt::BlockingQueuedConnection);
  11. connect(&tcpClient, SIGNAL(hostNotConnected(const QString&)), mTcpHandler, SLOT(hostNotConnected(const QString&)));
  12. connect(&tcpClient, SIGNAL(commandCame(QByteArray)), mTcpHandler, SLOT(analyzeCommand(QByteArray)));
  13. exec();
  14. }
  15. }
To copy to clipboard, switch view to plain text mode 


Can anyone help please?