QTcpSocket sometimes does not send data

I have two QT applications. We can assume that one application contains big data and sends about 10 KB of data every time per second for the second application.

I used to try to use QUdpSocket to transfer data, but due to the MTU limitation of about 2-5K and the need to divide and reconnect data, I switched to QTcpSocket.

Sometimes data is sent correctly with QTcpSocket (especially if I write data very often ~ every 100 ms), but sometimes data is not sent at all. Even after 5 seconds. And sometimes several data blocks are internally buffered for a long period (several seconds), and then sent together.

m_socket = new QTcpSocket(this); m_socket->connectToHost(QHostAddress::LocalHost, 45454); sendDataEverySec() { QByteArray datagram(10000, 'a'); qint64 len = m_socket->write(datagram); if(len != datagram.size()) qDebug() << "Error"; //this NEVER occurs in MY case. m_socket->flush(); } 

On the receiver side, I use the readyRead signal to know when the data arrived.

How can I guarantee the immediate sending of data? Are there any better alternatives to what I'm trying to do?

Edit :: When I write after long spaces in 1 second, I get "QAbstractSocket::SocketTimeoutError" on the receiver side every time the sender sends data. This error is not accepted if the sender often writes data.
Can I use QTcpSocket to stream data the way I do?

Edit 2: on the receiver side, when the readyRead signal is issued, I checked while(m_socket->waitForReadyRead(500)) again, and because of this I got "QAbstractSocket::SocketTimeoutError" . In addition, this check prevented the delivery of individual pieces.
After looking at additional documents, it seems that readyRead will be continuously emitted when new data is available, so there is no need for waitForReadyRead .
I get all the data sent, but still the data does not arrive immediately. Sometimes two or three pieces come together. This may be due to a delay on the receiver side when reading data, etc.

+6
source share
2 answers

On the receiver side, when the readyRead signal is emitted, I checked while(m_socket->waitForReadyRead(500)) again, and because of this I got "QAbstractSocket::SocketTimeoutError" . In addition, this check prevented the delivery of individual blocks.

After looking at additional documents, it seems readyRead will be continuously emitted when new data is available, so there is no need for waitForReadyRead . He solved my problem.

+2
source

my typical client server solution.

server side:

 class Server: public QTcpServer { public: Server(QObject *parent = 0); ~Server(); private slots: void readyRead(); void disconnected(); protected: void incomingConnection(int); }; 

on cpp:

 void Server::incomingConnection(int socketfd) { QTcpSocket *client = new QTcpSocket(this); client->setSocketDescriptor(socketfd); connect(client, SIGNAL(readyRead()), this, SLOT(readyRead())); connect(client, SIGNAL(disconnected()), this, SLOT(disconnected())); } void Server::disconnected() { QTcpSocket *client = (QTcpSocket*) sender(); qDebug() << " INFO : " << QDateTime::currentDateTime() << " : CLIENT DISCONNECTED " << client->peerAddress().toString(); } void Server::readyRead() { QTcpSocket *client = (QTcpSocket*) sender(); while (client->canReadLine()) { //here i needed a string.. QString line = QString::fromUtf8(client->readLine()).trimmed(); } } 

on the client:

class Client: public QTcpSocket {

 public: Client(const QHostAddress&, int, QObject* = 0); ~Client(); void Client::sendMessage(const QString& ); private slots: void readyRead(); void connected(); public slots: void doConnect(); }; 

on cpp:

 void Client::readyRead() { // if you need to read the answer of server.. while (this->canReadLine()) { } } void Client::doConnect() { this->connectToHost(ip_, port_); qDebug() << " INFO : " << QDateTime::currentDateTime() << " : CONNESSIONE..."; } void Client::connected() { qDebug() << " INFO : " << QDateTime::currentDateTime() << " : CONNESSO a " << ip_ << " e PORTA " << port_; //do stuff if you need } void Client::sendMessage(const QString& message) { this->write(message.toUtf8()); this->write("\n"); //every message ends with a new line } 
0
source

Source: https://habr.com/ru/post/910768/


All Articles