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[])
{
qDebug() << "========================== Client ========================";
Client myclient;
myclient.
Start(QUrl("http://10.77.32.14:2859"), bytes
);
// server ip is 10.77.32.14
return a.exec();
}
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();
}
To copy to clipboard, switch view to plain text mode
{
Q_OBJECT
public:
explicit Client
(QObject *parent
= 0);
~Client();
QNetworkAccessManager *m_manager;
QNetworkReply *m_reply;
signals:
public slots:
void onFinished();
void readData();
};
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();
};
To copy to clipboard, switch view to plain text mode
{
m_manager = new QNetworkAccessManager(this);
}
{
qDebug() << "Client::Start:";
QNetworkRequest request(url);
request.setHeader(QNetworkRequest::ContentTypeHeader, "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)
{
if (data.size() > 0)
{
qDebug() << "Client::readData(): data:" << str;
}
}
}
void Client::onFinished()
{
QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
qDebug() << "Client::onFinshed():";
if (reply) {
if (reply->error() == QNetworkReply::NoError) {
const int available = reply->bytesAvailable();
if (available > 0) {
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()
{
}
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::ContentTypeHeader, "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()
{
}
To copy to clipboard, switch view to plain text mode
======================= Server =================
int main(int argc, char *argv[])
{
qDebug() << "====================== Server ==========================";
Server myserver;
return a.exec();
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
qDebug() << "====================== Server ==========================";
Server myserver;
return a.exec();
}
To copy to clipboard, switch view to plain text mode
{
Q_OBJECT
public:
Server
(QObject * parent
= 0 , quint16 port
= 2859);
virtual ~Server();
private slots:
void acceptConnection();
void startRead();
void disconnected();
private:
};
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;
};
To copy to clipboard, switch view to plain text mode
{
connect(this, SIGNAL(newConnection()),this, SLOT(acceptConnection()));
}
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())
{
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());
}
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());
}
To copy to clipboard, switch view to plain text mode
Bookmarks