סטנלי גרונן
סטנלי גרונן

Reputation: 2997

Qt: Using QTcpSocket -> I can write on socket, but I can't read...

I am using Qt 4.8 GCC 32bit on xUbuntu 14.04.
I have the following piece of code, a TCP server that I use in order to get some remote commands and send back some answers - via TCP socket:

struct _MyRequest
{
    unsigned long   Request;
    unsigned long   Data;
} __attribute__((packed));

struct _MyAnswer
{
    unsigned long   Error;
    unsigned long   Filler;
} __attribute__((packed));

_MyRequest request;
_MyAnswer  answer;

RemoteCmdServer::RemoteCmdServer(QObject * parent)
    : QTcpServer(parent)
{
    qDebug() << "Server started";

    listen(QHostAddress("172.31.250.110"), 5004);

    connect(this, SIGNAL(newConnection()), this, SLOT(processPendingRequest()));
}

void RemoteCmdServer::processPendingRequest()
{
    qDebug() << "Process request";

    QTcpSocket * clientConnection = nextPendingConnection();
    connect(clientConnection, SIGNAL(disconnected()), clientConnection, SLOT(deleteLater()));

    // get the request
    int ret = clientConnection->read((char*)&request, sizeof(request));
    qDebug() << "READ: " << ret;
    if(ret == sizeof(request))
    {
        // send answer
        clientConnection->write((char*)&answer, sizeof(answer));
    }

    qDebug() << "Disconnecting...";
    clientConnection->disconnectFromHost();
}   

I am able to write correctly if I comment the if(ret == sizeof(request)) line.
Yet, I can't read from the socket (I always get 0 bytes).
I am 100% sure that the TCP-tool I use to send packets to my app works ok.
Here is the debug output from my app:

Server started     
Process request    
READ: 0     
Disconnecting...     

What am I doing wrong? Please advise!

Upvotes: 2

Views: 2794

Answers (2)

G.M.
G.M.

Reputation: 12879

You're trying to read data from the new connection without returning to the Qt event loop -- I don't think that's going to work.

After you've accepted the connect with...

QTcpSocket * clientConnection = nextPendingConnection();

You need to connect to its readyRead signal with something like...

connect(clientConnection, SIGNAL(readyRead()), this, SLOT(my_read_slot()));

Where my_read_slot is the member function that will actually perform the read operation.

Upvotes: 1

talamaki
talamaki

Reputation: 5472

You should wait for the data either in a non-blocking or blocking way. You can use waitForReadyRead to do it in a blocking way.

void RemoteCmdServer::processPendingRequest()
{
    qDebug() << "Process request";

    QTcpSocket * clientConnection = nextPendingConnection();
    connect(clientConnection, SIGNAL(disconnected()), clientConnection, SLOT(deleteLater()));

    if (clientConnection->waitForReadyRead())
    {
        // get the request
        QByteArray message = clientConnection->readAll(); // Read message
        qDebug() << "Message:" << QString(message);
    }
    else
    {
        qDebug().nospace() << "ERROR: could not receive message (" << qPrintable(clientConnection->errorString()) << ")";
    }

    qDebug() << "Disconnecting...";
    clientConnection->disconnectFromHost();
}

Upvotes: 1

Related Questions