Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-31027

QLocalSocket::readyRead() signal does not work as expected

    XMLWordPrintable

Details

    • Bug
    • Resolution: Invalid
    • Not Evaluated
    • None
    • 5.0.2
    • Network: Sockets
    • None
    • Windows 7 64bit, Visual Studio 2010 SP1, Qt5.0.2 for msvc2010 32bit

    Description

      The communication between two processes via QLocalSocket breaks after some time. It seems to be a regression bug because the code works fine with Qt4.8.4.
      The Test-Setup is attached as QtCreator project.

      Test-Setup:
      1. A server process that starts a QLocalServer
      2. A client process that connects to the server and tries to write continously a message (in our case just 6 bytes, 2 bytes as size information of type quint16 and 4 bytes as running number of type qint32)
      3. When the client is connected to the server...
        • ...the client sends messages to the server and writes via qDebug() the message count whenever 1000 messages are sent, additionally the client sleeps every 1000 messages for a duration of 500ms.
        • ...the server receives the client messages, checks the running number (previous number = current number - 1) and writes via qDebug() the running number or stops if an error occurs.
      Steps to reproduce:

      1. Start the server
      2. Start the client

      Result

      After some time it seems as if some bytes will be lost so that the running number check will fail. Usually, the effect takes place in less than 60 seconds. You can increase the chance by increasing the CPU usage, for example by opening a browser. Another way could be to increase the byte count of the messages.

      Code

      Here is the function that is connected to the readyRead() signal of class QLocalSocket. _previousNumber is a member variable of class Socket

      socket.cpp
      void Socket::read()
      {
          while (!_socket->atEnd())
          {
              // check that at least 2 bytes are available
              if (_socket->bytesAvailable() < 2)
                  return;
      
              // read these two bytes
              QDataStream sizeStream(_socket->read(2));
      
              // reinterpret these two bytes as size information of type quint16
              quint16 dataCount(0);
              sizeStream >> dataCount;
      
              // read more bytes as specified by 'dataCount'
              QDataStream dataStream(_socket->read(dataCount));
      
              // reinterpret data as qint32
              int currentNumber(0);
              dataStream >> currentNumber;
      
              qDebug() << currentNumber;
      
              // check running number
              if (_previousNumber != currentNumber - 1)
              {
                  // stop listening
                  qDebug() << ";-(";
                  disconnect(_socket, SIGNAL(readyRead()), this, SLOT(read()));
                  break;
              }
      
              _previousNumber = currentNumber;
          }
      }
      

      Again, this code works fine with Qt4.8.4. As workaround we avoid the readyRead() signal and poll the socket by a QTimer instead.

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            jbornema Joerg Bornemann
            rene René Keimling
            Votes:
            1 Vote for this issue
            Watchers:
            4 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes