PDA

View Full Version : Client QNetworkReply is returning Connection Closed Status



mut
9th October 2015, 04:51
Hello;

Based on the different code/examples found online, I have built a bidirectional qt http communication between server (on a linux machine) and client (on another linux machine).
The requirement is to use PUT on the client side.
Server is able to receive data from client but I'm having these problems in the direction: server -> client:

- Client: No emission of the readyRead() signal
- Client: QNetworkReply status is returning "Connection Closed" inside the function onFinished() slot
- Server: client->write() is failing with "QIODevice::write: device not open" and also "disconnected" signal is emitted.

Any thoughts/hints on why I'm encountering these problems?

Thank you very much in advance.

Mut.

=================== Client Part =============


int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);

qDebug() << "========================== Client ========================";
Client myclient;

QByteArray bytes("Hello");

myclient.Start(QUrl("http://10.77.32.14:2859"), bytes); // server ip is 10.77.32.14

return a.exec();
}



class Client : public QObject
{
Q_OBJECT
public:
explicit Client(QObject *parent = 0);
~Client();


QNetworkAccessManager *m_manager;

void Start(const QUrl url, const QByteArray array);

QNetworkReply *m_reply;

signals:

public slots:

void onFinished();
void readData();
};



Client::Client(QObject *parent) : QObject(parent)
{
m_manager = new QNetworkAccessManager(this);
}

void Client::Start(const QUrl url, const QByteArray array)
{
qDebug() << "Client::Start:";

QNetworkRequest request(url);
request.setHeader(QNetworkRequest::ContentTypeHead er, "text/plain");

request.setUrl(url);

m_reply = m_manager->post(request, array);

m_reply->ignoreSslErrors();

bool ok = QObject::connect(m_reply, SIGNAL(finished()), this, SLOT(onFinished()));
ok = QObject::connect(m_reply, SIGNAL(readyRead()), this, SLOT(readData()));

Q_ASSERT(ok);
}

void Client::readData()
{
qDebug() << "Client::readData()";

if (NULL != m_reply)
{
QByteArray data = m_reply->readAll();

if (data.size() > 0)
{
QString str(data);
qDebug() << "Client::readData(): data:" << str;
}
}
}

void Client::onFinished()
{
QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());

qDebug() << "Client::onFinshed():";

QString response;
if (reply) {
if (reply->error() == QNetworkReply::NoError) {
const int available = reply->bytesAvailable();
if (available > 0) {
const QByteArray buffer(reply->readAll());
response = QString::fromUtf8(buffer);

qDebug() << "Client Received:" << response;
}
} else {
response = tr("Error: %1 status: %2").arg(reply->errorString(), reply->attribute(QNetworkRequest::HttpStatusCodeAttribute ).toString());
qDebug() << response;
}

reply->deleteLater();
}

if (response.trimmed().isEmpty()) {
response = tr("Unable to retrieve post response");
}
}

Client::~Client()
{

}


======================= Server =================


int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);

qDebug() << "====================== Server ==========================";

Server myserver;

return a.exec();
}



class Server: public QTcpServer
{

Q_OBJECT
public:

Server(QObject * parent = 0 , quint16 port = 2859);
virtual ~Server();

private slots:

void acceptConnection();
void startRead();
void disconnected();

private:

QTcpSocket * client;

};



Server::Server(QObject* parent , quint16 port): QTcpServer(parent)
{
connect(this, SIGNAL(newConnection()),this, SLOT(acceptConnection()));

listen(QHostAddress::Any, port );
}

Server::~Server()
{
qDebug() << "Server destructor called:";
delete client;
close();
}

void Server::acceptConnection()
{
client = nextPendingConnection();

connect(client, SIGNAL(readyRead()), this, SLOT(startRead()));
connect(client, SIGNAL(disconnected()), this, SLOT(disconnected()));

qDebug() << "New client from:" << client->peerAddress().toString();
}

void Server::startRead()
{
while(client->canReadLine())
{
QString line = QString::fromUtf8(client->readLine()).trimmed();
qDebug() << "Client :" << line;

client->write(QString("Server : I've taken your message (:\n").toUtf8());
client->flush();
}

}

void Server::disconnected()
{
qDebug() << "Client disconnected:" << client->peerAddress().toString();

client->write(QString("Server : I wish you didn't leave ):\n").toUtf8());
}

anda_skoa
9th October 2015, 12:39
Have you tried sending a valid HTTP response?

Cheers,
_

mut
9th October 2015, 18:10
Thanks for the reply. I'm not sure that I understand what you mean by sending a valid HTTP response?

anda_skoa
10th October 2015, 10:01
Well, you are using QNetworkAccessManager on a HTTP URL.
But your server does not respond with an HTTP response, but with just a string.

It is very likely that the HTTP handler on the client aborts the connection when it gets this unexpected and (for HTTP) invalid data.

Hence the suggestion to try sending a valid response and see if that fixed the problems you are observing.

Cheers,
_

mut
13th October 2015, 23:42
Thanks for the reply. You are absolutely right, sending a valid HTTP reply is fixing the problem. Ex:

/* Respond with a basic HTTP message. */
client->write("HTTP/1.1 200 OK\r\n"
"Content-type: text/plain\r\n"
"Content-length: 12\r\n"
"\r\n"
"Hello World!");