3

I have an application in c++/Qt in Windows, Linux and MacOSX, and I have a local client-server mechanism using Qt Local Server/Socket.

When the server refuses a connection, I send a message and close the socket, using QLocalSocket::disconnectFromServer()

From the documentation I see

If there is pending data waiting to be written, QLocalSocket will enter ClosingState and wait until all data has been written.

So in the client side, I connect the signal QLocalSocket::disconnected and do the following in my slot

void MyClientClass::onSocketDisconnected()
{
   qDebug() << "Socket disconnected";
   socket->readAll();
    //I do something with the data read
}

But it happens that sometimes, mostly on slow Linux machines (I try with virtual machines with only 1 processor), I do not receive the last message that the server send just before closing.

Why this happens? It should be in contrast with the documentation, shouldn't it?

Is there some motivation why I noticed it only in Linux and MacOSX (where Qt uses unix domain sockets) and I did not noticed it in Windows (where Qt uses pipes)?

Maybe there is some motivation related to domain sockets? Or I just misunderstood something?

Edit: as written in the comments below, in these cases when I do not receive the message, also the QLocalSocket::ClosingState is missing and I receive directly the QLocalSocket::UnconnectedState

Edit 2: as suggested in comments, I tried the waitForReadyRead() function. I did it onSocketDisconnected() and also onStateChanged() when the state goes to QLocalSocket::ClosingState or QLocalSocket::UnconnectedState. When I receive the QLocalSocket::ClosingState everything goes well, but the problem, as I said in the last edit, is that sometimes QLocalSocket::ClosingState is missing. In this case, the waitForReadyRead() fails without waiting the timeout and I have a warning "QIODevice:read (QTcpSocket): device not open" (even if I am using QLocalSocket, maybe the warning message is not updated well in Qt source). By the way, I am using Qt5.7.

n3mo
  • 663
  • 8
  • 23
  • Maybe you have to handle `QLocalSocket::stateChanged()` signal and its `QLocalSocket::ClosingState` state in the corresponding slot? I guess the `disconnected()` signal emits after `stateChanged()` one. – vahancho Feb 14 '18 at 08:10
  • hi vahancho, thanks for the suggestion, but unfortunately it does not work...I logged the `stateChanged()` signal and I get only the `QLocalSocket::UnconnectedState` after a `QLocalSocket::PeerClosedError`. The `QLocalSocket::ClosingState` sometimes is missing. I try to read the available data in two slots, `onError()` and `onStateChange()`, but I still don't get the last message (in Ubuntu16 virtual machine with 1 processor and 1gb RAM I can reproduce it 30% of times). – n3mo Feb 15 '18 at 10:25
  • You are reading the socket _without waiting it to complete writing_ so you have to connect to the signal `waitForReadyRead()` in order to read a socket correctly. – Mohammad Kanan Feb 15 '18 at 23:04
  • Hi Mohammad, I will try your suggestion. Anyway, it is written in doc in `disconnectFromServer()` function that "will enter ClosingState and _wait until all data has been written_". A part of that, I also do a redundary `flush()` _before_ closing it. But I will try and tell you the result thanks. Edit: another thing. From `waitForReadyRead()` doc: "This function blocks until data is available for reading and the readyRead() signal has been emitted". I already check the `readyRead()` signal, so why should I wait? – n3mo Feb 16 '18 at 07:43
  • Hi Mohammad, I confirm that your suggestion did _not_ work :( see the edit question for the details. – n3mo Feb 16 '18 at 09:07

0 Answers0