I wrote a program for client on Qt to receive data from server but it is not receiving data and showing received bytes as zero,following is my program:
//client.h
#ifndef CLIENT_H
#define CLIENT_H
#include <QObject>
#include <QString>
#include <QtNetwork/QTcpSocket>
class Client: public QObject
{
Q_OBJECT
public:
Client(QObject* parent = 0);
~Client();
void start(QString address, quint16 port);
void send(const char*);
void receive();
public slots:
void startTransfer();
private:
QTcpSocket client;
};
#endif // CLIENT_H
//client.cpp
#include "client.h"
#include <QtNetwork/QHostAddress>
#include<QIODevice>
Client::Client(QObject* parent): QObject(parent)
{
connect(&client, SIGNAL(connected()),
this, SLOT(startTransfer()));
//connect(&client, SIGNAL(waitForBytesWritten()),
// this, SLOT(receive()));
}
Client::~Client()
{
client.close();
}
void Client::start(QString address, quint16 port)
{
QHostAddress addr(address);
client.connectToHost(addr, port);
}
void Client::startTransfer()
{
client.write("Connection Established", 22);
}
void Client::send(const char *buffer)
{
client.write(buffer,sizeof(buffer));
}
void Client::receive()
{
char temp[1024] = {0};
int len = client.read(temp,client.bytesAvailable());
printf("\tData recieved from server :: %s\n",temp);
printf("\tSize of data received is :: %d\n",client.bytesAvailable());
printf("\tBytes read is :: %d\n",len);
}
//main.cpp
#include <QCoreApplication>
#include "client.h"
//#include <QApplication>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Client client;
client.start("192.168.1.2", 9602);
char buff[] = "Send operation performed from main";
client.send(buff);
// while(1)
client.receive();
return a.exec();
}
Here my program function executes and then stops receiving(may be),when I send any thing from server it doesn't take anything.Any suggestions?
Plz don't be rude if I have done any silly programming mistake because I'm newbie.
You are not getting #Merlin069's answer....you should use readyRead in signal's place and your receieve function as slot...it will work.I hope this much easy language is understandable to you.
You can try using while(1) and inside it write your receive function
Related
i'm planning do a little app desktop with Qt Creator. I'm using QUdpSocket class to make a simple connection through UDP, in fact i used a test code i found on internet, but my problem is when i run the code and the console just show me the port and the message, not the ip address where come from the message. Could someone tell me what i'm doing bad?
The source reference is this
This is the header file:
#ifndef PRUEBAUDP_H
#define PRUEBAUDP_H
#include <QObject>
#include <QUdpSocket>
#include <QDebug>
/*#include <QNetworkDatagram>
#include <QHostAddress>*/
class pruebaUDP : public QObject
{
Q_OBJECT
public:
explicit pruebaUDP(QObject *parent = nullptr);
void mensajeSocket();
signals:
public slots:
void readyRead();
private:
QUdpSocket *udpSocket;
};
#endif // PRUEBAUDP_H
This is the source file:
#include "pruebaudp.h"
pruebaUDP::pruebaUDP(QObject *parent) : QObject(parent)
{
udpSocket = new QUdpSocket(this);
udpSocket->bind(QHostAddress::LocalHost, 1234);
connect(udpSocket, SIGNAL(readyRead()),
this, SLOT(readyRead()));
}
void pruebaUDP::mensajeSocket()
{
QByteArray dato;
dato.append("hola");
udpSocket->writeDatagram(dato, QHostAddress::LocalHost, 1234);
}
void pruebaUDP::readyRead()
{
QByteArray buffer;
buffer.resize(udpSocket->pendingDatagramSize());
QHostAddress sender;
quint16 senderPort;
udpSocket->readDatagram(buffer.data(), buffer.size(), &sender, &senderPort);
qDebug() << "Desde: " << sender.toString();
qDebug() << "mensaje del puerto: " << senderPort;
qDebug() << "mensaje: " << buffer;
}
and this is the main file:
#include <QCoreApplication>
#include "pruebaudp.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
pruebaUDP prueba;
prueba.mensajeSocket();
return a.exec();
}
This is a input screenshot:
You use same socket for sending and receiving.
Try to send data via other socket, i.e.
void pruebaUDP::mensajeSocket()
{
QByteArray dato;
dato.append("hola");
static QUdpSocket * socket = new QUdpSocket(this);
socket->writeDatagram(dato, QHostAddress::LocalHost, 1234);
}
There is no error in my code though there is never any request packet hits my server. I run tcpdump port 80 and nothing ever crosses the wire, wireshark says the same.
//coreeng.h
#ifndef COREENG_H
#define COREENG_H
#include <QObject>
#include <QNetworkAccessManager>
class coreEng : public QObject
{
Q_OBJECT
public:
private slots:
public slots:
void connect();
void url();
void finishedSlot(QNetworkReply* reply);
private:
QNetworkAccessManager* nam;
};
#endif // COREENG_H
//coreengine.cpp
#include "coreeng.h"
#include <QNetworkAccessManager>
#include <QUrl>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QImageReader>
coreEng::coreEng(QObject *parent) :
QObject(parent)
{
}
explicit coreEng(QObject *parent = 0)
{
nam = new QNetworkAccessManager();
}
void coreEng::connect(){
QObject::connect(nam, SIGNAL(finished(QNetworkReply*)),
this, SLOT(finishedSlot(QNetworkReply*)));
}
void coreEng::url(){
QUrl url("http://www.myserver.com");
QNetworkReply* reply = nam->get(QNetworkRequest(url));
}
void coreEng::finishedSlot(QNetworkReply* reply){
QVariant statusCodeV = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
QVariant redirectionTargetUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
if (reply->error() == QNetworkReply::NoError)
{
QImageReader imageReader(reply);
QImage pic = imageReader.read();
QByteArray bytes = reply->readAll(); // bytes
QString string(bytes); // string
}
else
{
}
delete reply();
}
//main.cpp
#include <QCoreApplication>
#include "coreeng.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
coreEng mConnect;
mConnect.connect();
return a.exec();
}
You never call coreEng::url() so you never make a request.
I'm also not sure your constructors are correct. Why not just ditch the explicit constructor and create the QNetworkAccessManager in the default constructor?
I am trying to implement http://developer.nokia.com/community/wiki/Creating_an_HTTP_network_request_in_Qt and my code compiles without error but does not function. I have a warning that reply in "QNetworkReply* reply = nam->get(QNetworkRequest(url));" is not being used. I am sure this is my error and I am not setting up my HTTP GET correctly, but I am unsure of how to correct it.
//coreEng.h
#ifndef COREENG_H
#define COREENG_H
#include <QObject>
#include <QNetworkAccessManager>
class coreEng : public QObject
{
Q_OBJECT
public:
//coreEng(QObject);
coreEng(QObject *parent = 0) :
QObject(parent)
{
nam = new QNetworkAccessManager();
}
private slots:
public slots:
void connect();
void url(QNetworkReply *reply);
void finishedSlot(QNetworkReply* reply);
private:
QNetworkAccessManager* nam;
};
#endif // COREENG_H
//coreEng.cpp
"coreeng.h"
#include <QNetworkAccessManager>
#include <QUrl>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QImageReader>
void coreEng::connect(){
QObject::connect(nam, SIGNAL(finished(QNetworkReply*)),
this, SLOT(finishedSlot(QNetworkReply*)));
}
void coreEng::url(QNetworkReply*){
QUrl url("http://www.nyctelecomm.com");
QNetworkReply* reply = nam->get(QNetworkRequest(url));
}
void coreEng::finishedSlot(QNetworkReply* reply){
QVariant statusCodeV = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
QVariant redirectionTargetUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
if (reply->error() == QNetworkReply::NoError)
{
QImageReader imageReader(reply);
QImage pic = imageReader.read();
QByteArray bytes = reply->readAll(); // bytes
QString string(bytes); // string
}
else
{
}
//delete reply();
}
//main.cpp
#include <QCoreApplication>
#include "coreeng.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
coreEng mConnect;
mConnect.connect();
return a.exec();
}
changed void coreEng::url(QNetworkReply*) to void coreEng::url()
changed void url(QNetworkReply *reply); to void url();
added mConnect.url(); to main.cpp and I could see the http packet with wireshark exit the NIC and begin the session.
I try to create a simple ssl connection between a client and a server in QtNetwork.
But I have a problem. First I run the server. Then I run the client. When I first run the client nothing happens, but when I run it second time I get QSslSocket::startServerEncryption: cannot start handshake on non-plain connection. I don't know how to fix it.
Here is the server:
//server.h
#ifndef SERVER_H
#define SERVER_H
#include <QtNetwork>
#include <QObject>
#include <QTcpServer>
#include <QTcpSocket>
#include <QSslSocket>
class Server: public QTcpServer
{
Q_OBJECT
public:
Server(QObject * parent = 0);
void incomingConnection(int handle);
~Server();
public slots:
void startRead();
private:
QSslSocket* socket;
};
#endif // SERVER_H
Server Source File :
//server.cpp
#include "server.h"
#include <iostream>
#include <QByteArray>
#include <QSslCertificate>
#include <QSslKey>
using namespace std;
Server::Server(QObject* parent) :
QTcpServer(parent)
{
socket = new QSslSocket;
connect(socket, SIGNAL(encrypted()),
this, SLOT(startRead()));
listen(QHostAddress::Any, 8889);
}
void Server::startRead()
{
char buffer[1024] = { 0 };
socket->read(buffer, socket->bytesAvailable());
cout << buffer << endl;
socket->close();
}
void Server::incomingConnection(int socketDescriptor)
{
if (socket->setSocketDescriptor(socketDescriptor))
{
connect(socket, SIGNAL(encrypted()),
this, SLOT(startRead()));
QByteArray key;
QByteArray cert;
QFile file_key("/path_to_key/rsakey");
if(file_key.open(QIODevice::ReadOnly))
{
key = file_key.readAll();
file_key.close();
}
else
{
qDebug() << file_key.errorString();
}
QFile file_cert("/path_to_certificate/mycert.pem");
if(file_cert.open(QIODevice::ReadOnly))
{
cert = file_cert.readAll();
file_cert.close();
}
else
{
qDebug() << file_cert.errorString();
}
QSslKey ssl_key(key, QSsl::Rsa);
QSslCertificate ssl_cert(cert);
socket->setPrivateKey(ssl_key);
socket->setLocalCertificate(ssl_cert);
QSslConfiguration cfg = socket->sslConfiguration();
cfg.caCertificates();
socket->startServerEncryption();
}
}
Server::~Server()
{
delete socket;
}
Server Main File :
//server main
#include "server.h"
#include <QCoreApplication>
int main(int argc, char** argv)
{
QCoreApplication app(argc, argv);
Server server;
return app.exec();
}
Here is the Client :
//client.h
#ifndef CLIENT_H
#define CLIENT_H
#include <QtNetwork>
#include <QObject>
#include <QString>
#include <QSslSocket>
class Client: public QObject
{
Q_OBJECT
public:
Client(QObject* parent = 0);
~Client();
void start(QString address, quint16 port);
public slots:
void startTransfer();
private:
QSslSocket client;
};
#endif // CLIENT_H
Client Source File :
// client.cpp
#include "client.h"
#include <QDebug>
Client::Client(QObject* parent) :
QObject(parent)
{
connect(&client, SIGNAL(encrypted()),
this, SLOT(startTransfer()));
}
Client::~Client()
{
client.close();
}
void Client::start(QString address, quint16 port)
{
client.connectToHostEncrypted(address, port);
}
void Client::startTransfer()
{
qDebug() << "startTransfer()";
client.write("Hello, world", 13);
}
Client Main File :
//client main
#include "client.h"
#include <QCoreApplication>
int main(int argc, char** argv)
{
QCoreApplication app(argc, argv);
Client client;
client.start("127.0.0.1", 8889);
return app.exec();
}
Anyone can tell me what's missing?
The problem here is that QSslSocket can't be reused (I opened a bug about this QTBUG-59348), so once you call setSocketDescriptor for the second time (once a new connection arives) the internal mode is in Encrypted state.
Your code also has the issue that even if QSslSocket could be reused, you create a single socket at the constructor, so you can only accept a single connection at time. You must instead create a new QSslSocket inside incommingConnection, and NO YOU DON'T NEED to call nextPendingConnection() if you have an implementation of QTcpServer, if you do you will get two objects pointing to the same FD, one QTcpSocket and one QSsqSocket created by you.
You should try to get the socket descriptor from the nextPendingConnection and set the socket descriptor of the QSslsocket
First: You have to connect the signal of the QTcpServer::newConnection with a self made slot (for example newConnectionRecognized)
Second: Set the socketDescriptor of the QSslSocket with the socket descriptor of the QTcpServer::nextPendingConnection()->socketDescriptor
constructor:
{
server = new QTcpServer;
...
server->listen(QHostAddress::Any,1234)
...
connect(server,SIGNAL(newConnection()),this,SLOT(newConnectionRecognized()));
...
}
void SslServer::newConnectionRecognized()
{
incomingConnection(server->nextPendingConnection()->socketDescriptor());
...
}
void SslServer::incomingConnection(int socket_descriptor)
{
socket = new QSslSocket(this);
...
if (!socket->setSocketDescriptor(socket_descriptor))
{
qWarning("! Couldn't set socket descriptor");
delete socket;
return;
}
...
}
I hope it helped...
I want to write a console chat program in qt framework.I have a problem with sending messages.
Client sends messages to server but server doesn't take the messages until client program is closed.When client is closed, server displays all messages.I don't want that.I want server to get my messages when i send to it.
I wrote the codes below.You will see what i want to do if you look at main function of client.
/*
Created BY :
Creation DATE : 26/10/2012
Client interface
*/
#ifndef CLIENT_H
#define CLIENT_H
#include <QtNetwork>
#include <QObject>
#include <QtNetwork/QTcpSocket>
namespace NetworkArdic
{
class Client : public QObject
{
Q_OBJECT
public:
Client(QObject * obj = 0,QString add="localhost", quint16 port = 4000);
void SendData(QString data);
virtual ~Client();
private slots:
void ReadData();
void connected();
private:
QTcpSocket *socket;
};
}
#endif
/*
Created BY :
Creation DATE : 26/10/2012
Client source file
*/
#include "Client.h"
#include <QHostAddress>
#include <iostream>
using namespace std;
namespace NetworkArdic{
Client::Client(QObject * obj, QString add, quint16 port) : QObject(obj)
{
socket = new QTcpSocket(this);
connect(socket, SIGNAL(readyRead()), this, SLOT(ReadData()));
connect(socket, SIGNAL(connected()), this, SLOT(connected()));
socket->connectToHost(QHostAddress(add), port);
}
Client::~Client(){
socket->close();
delete socket;
}
void Client::SendData(QString data)
{
if(!data.isEmpty())
{
socket->write(QString(data + "\n").toUtf8());
}
}
void Client::ReadData()
{
while(socket->canReadLine())
{
QString line = QString::fromUtf8(socket->readLine()).trimmed();
qDebug() << line;
}
}
void Client::connected()
{
socket->write(QString("Client : Server connection has been made (: \n").toUtf8());
}
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Client cli(0,"127.0.0.1",4000);
string line;
while(line!="exit"){
cout << "Message : ";
cin >> line;
cli.SendData(QString(line.c_str()));
}
return a.exec();
}
/*
Created BY :
Creation DATE : 26/10/2012
Server interface
*/
#ifndef SERVER_H
#define SERVER_H
#include <QtNetwork>
#include <QObject>
#include <QtNetwork/QTcpServer>
#include <QtNetwork/QTcpSocket>
namespace NetworkArdic
{
class Server: public QTcpServer
{
Q_OBJECT
public:
Server(QObject * parent = 0 , quint16 port = 4000);
virtual ~Server();
private slots:
void acceptConnection();
void startRead();
void disconnected();
private:
QTcpSocket * client;
};
}
#endif // SERVER_H
/*
Created BY :
Creation DATE : 26/10/2012
Server source file
*/
#include "Server.h"
#include <iostream>
using namespace std;
namespace NetworkArdic{
Server::Server(QObject* parent , quint16 port): QTcpServer(parent)
{
connect(this, SIGNAL(newConnection()),this, SLOT(acceptConnection()));
listen(QHostAddress::Any, port );
}
Server::~Server()
{
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());
}
}
void Server::disconnected()
{
qDebug() << "Client disconnected:" << client->peerAddress().toString();
client->write(QString("Server : I wish you didn't leave ):\n").toUtf8());
}
}
Try using socket->flush() after you write the data.
http://doc.qt.digia.com/qt/qabstractsocket.html#flush
You used the code below to read socket data.
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());
}
}
I suggest to adopt from the following code which I have tested works
while (tcp_server->hasPendingConnections()) {
client = tcp_server->nextPendingConnection();
client->waitForReadyRead(100);
QByteArray byteArray = client->readAll();
QString s_data = byteArray.data();
// Process s_data
client->close();
client->abort();
}