Question

I need help with QTcpSocket's rising memory.

Of course I have found similar questions here, here and here, but unfortunately they are not solving this issue for me.

I wrote a simple class which encapsulates QTcpSocket:

#include "GWCommunicator.h"

GWCommunicator::GWCommunicator() {
    socket = new QTcpSocket(this);
}

    bool GWCommunicator::send(const char *data, qint64 size) {
        socket->write(data, size);
        return socket->waitForBytesWritten();
    }

    GWCommunicator::~GWCommunicator() {
        delete socket;
    }

    bool GWCommunicator::connectToServer() {
        socket->connectToHost(SERVERIP, 6498, QIODevice::ReadWrite);
        return socket->waitForConnected();
    }

    bool GWCommunicator::disconnectFromServer() {
        socket->disconnectFromHost();
        return socket->waitForDisconnected();
    }

Where socket is QTcpSocket* declared as a private field in header file.

In the manner of functionality, everything is fine. But this socket consumes more and more memmory with each message sent. It is not an actual leak, but some kind of buffering (which correspond with QIODevice documentation - note for QTcpSocket). Docs also says that you can use Unbuffered mode when opening device. But this is not posible in QTcpSocket:

Note: TCP sockets cannot be opened in QIODevice::Unbuffered mode.

How should I avoid it? I understood that waitForBytesWritten() should do it but it obviously does not.

main class looks like this:

#include "GWCommunicator.h"
#include <iostream>

using namespace std;

GWCommunicator *communicator;

int main(/*int argc, char *argv[]*/) {
    communicator = new GWCommunicator();
    communicator->connectToServer();

    string stdstr("Hello world");
    const char* str = stdstr.c_str();
    int count = 0;
    int length = stdstr.size();

    while (count++ < 10000) {
        communicator->send(str, length);
    }

    communicator->disconnectFromServer();
    delete communicator;
    return 0;
}

And my header file is following.

#include <QObject>
#include <QTcpSocket>

#ifndef GWCOMMUNICATOR_H
#define GWCOMMUNICATOR_H

#define SERVERIP "127.0.0.1"

class GWCommunicator : private QObject {
    Q_OBJECT

public:
    GWCommunicator();
    ~GWCommunicator();
    bool connectToServer();
    bool disconnectFromServer();
    bool send(const char *datam, qint64 size);

private:
    QTcpSocket *socket;

};

#endif  /* GWCOMMUNICATOR_H */
Was it helpful?

Solution

So as pointed out by @MarekR, the reason for this "leak" is no reading from the socket. So the QTcpSocket is buffering responses from server. This allocated memmory is released after retreiving incoming data from socket.

OTHER TIPS

It takes two to tango. You write into the socket all the while ignoring whether the other end of the connection has read anything from said socket.

You are solely responsible for the growth of the write buffer. You should check the write buffer size (available via bytesToWrite) and cease writing to the socket if it's past some threshold that you feel comfortable about.

There's absolutely no magic to it: you, and only you, make that buffer grow.

The growth of the write buffer, as indicated by bytesToWrite is an indication that you're writing faster than the other side reads the data. There can be various reasons for that, such as:

  • slow communications channel,

  • badly implemented server.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top