Good day. There is a project in which QTcpSocket is used and it looks like this in the general case:

QTcpSocket *Q_socket = new QTcpSocket(this); Q_socket->setSocketOption(QAbstractSocket::LowDelayOption, 1); if (Q_socket == NULL) { return error ;// сокет не открылся } for (int cnt = 0; cnt < send_sequence_length; cnt++) // { //заполняем массив на отправку data_send[to_send_counter] = to_send_array[cnt]; to_send_counter++; //когда он заполнился if (to_send_counter == 32) //Отсылаем по 32 { send_error = Q_socket->write((char*) &data_send, 32*sizeof(ToSend)); if (send_error == -1) { return error = -5; //ошибка приёма/передачи } to_send_counter = 0; } } RecData = Q_socket->readAll(); Q_socket->close(); Q_socket->waitForDisconnected(); 

The problem is that when reading it, it returns nothing - RecData remains empty. When setting a breakpoint, it will only send a small number of packets, and after continuing with the program, the rest will not return anything when reading. In this case, all the packages reach the addressee, this is confirmed on the receiving side. How should the data be read, with what delay, or in general to open another socket for this?

  • readAll will read all available data in the buffer. If the data has not yet reached, then this function will not read it. Why? but she just does not know how much to read. Therefore, you need to organize a cycle and read exactly as much as you need, passing the size in the first bytes or reading to the end of the line. - KoVadim
  • @KoVadim I did it through ready_read. He skipped operations and did not return anything even with large delays - Taras Kolesko
  • one
    better to subscribe to the signal readyRead and receive everything there. - KoVadim
  • The problem is that no signal comes from a remote server for any signal. WireShark does not see them, but this is a common problem, I read shark blindness articles on QT sockets. Maybe it is worth giving him sleep or other delay in order to process and accept? - Taras Wheel
  • one
    Wireshark has no blindness on Qt sockets. These are the same sockets as everyone else. Another thing is that wireshark under Windows does not see packages on localhost, but these are features of Windows. But if the packets do not come from the remote server, then maybe he just does not send them? - KoVadim

2 answers 2

Working with sockets in Qt is asynchronous. It is useless to try to send data and expect that the answer will immediately come, while blocking the event manager, which in turn is enabled via QCoreApplication::exec() .

The QAbstractSocket::waitForBytesWritten() and QAbstractSocket::waitForReadyRead() , although they implement blocking calls, can nevertheless behave incorrectly in Windows, which is honestly warned about in the help.

The only reliable way to wait for the socket notification of the arrival of a new piece of data is to connect to the QIODevice::readyRead() signal. The word "portion" is the key and implies that not all the data that was sent by the transmitting side are necessarily already received and ready to be read.

Total, fundamental points are:

  1. creating a socket object;
  2. connection to a remote server;
  3. sending data;
  4. leaving to wait for a response, but not using sleep , namely, through the activation of an event handler;
  5. receiving a response on a signal with processing for the possibility of data coming in parts.

Connection organization and data acquisition can be performed, for example, as follows:

 int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); QSharedPointer<QTcpSocket> socket(new QTcpSocket()); connect(socket.data(), &QTcpSocket::connected, [socket]() { connect(socket.data(), &QTcpSocket::readyRead(), [socket]() { qDebug() << socket->readAll(); }); socket->write("tra-ta-ta"); }); socket->connectToHost("127.0.0.1", 9999); return app.exec(); } 
  • Thank you, very clearly explained. It is a pity, of course, that everything is not as simple as in C ++ or in C #, I did not want to produce more signal slots, but your decision helped. - Taras Wheel
  • @ TarasKolesko, please. In Qt, the GUI is prioritized, and therefore asynchrony is focused on not to “freeze” the user interface. - alexis031182

Not enough karma to write in a comment. It seems you can make a delay through QEventLoop. For example, something like:

 QEventLoop wait; connect (Q_socket, SIGNAL(finished()), &wait, SLOT(quit())); QTimer::singleShot(10000, &wait, SLOT(quit())); wait.exec();