I'm learning about using QFtp.
I'd like to connect to a remote ftp server and list its content.
This what I wrote so far:
// libftp.cpp
#include "libftp.h"
libFTP::libFTP(QObject *parent) :
QObject(parent)
{
}
void libFTP::open(QString host)
{
connect(&ftp,SIGNAL(commandFinished(int,bool)),this,SLOT(status(int,bool)));
connect(&ftp,SIGNAL(listInfo(QUrlInfo)),this,SLOT(dir(QUrlInfo)));
ftp.setTransferMode(QFtp::Active);
ftp.connectToHost(host);
ftp.list();
ftp.cd("USER");
}
void libFTP::disconnect()
{
ftp.abort();
ftp.deleteLater();
}
void libFTP::download(QString filename)
{
ftp.get(filename);
}
void libFTP::upload(QString path,QString filename)
{
QString fullpath=path+filename;
try
{
QFile *f= new QFile(fullpath);
if(f->exists())
{
qDebug()<<"File Trovato";
ftp.mkdir("test");
//ftp.put(f,filename);
f->close();
f->deleteLater();
}
}
catch(std::exception x)
{
qDebug()<<"Errore " << x.what();
}
}
void libFTP::status(int id,bool error)
{
if(error)
{
qDebug()<<"Errore";
}
else
qDebug()<<"Status ID " << QString(id);
}
void libFTP::dir(QUrlInfo directory)
{
qDebug()<<directory.name();
}
// libftp.h
#ifndef LIBFTP_H
#define LIBFTP_H
#include <QObject>
#include <QtCore>
#include <QFtp>
#include <QUrlInfo>
class libFTP : public QObject
{
Q_OBJECT
public:
explicit libFTP(QObject *parent = 0);
void open(QString host);
void disconnect();
void download(QString filename);
void upload(QString path,QString filename);
private:
QFtp ftp;
signals:
public slots:
void status(int id,bool error);
void dir(QUrlInfo directory);
};
#endif // LIBFTP_H
And I call it from main:
#include <libftp.h>
int main()
{
libFTP *ftp = new libFTP();
ftp->open("10.20.xx.xxx");
ftp->deleteLater();
}
The server I'm connecting to accepts anonymous login.
When I try to debug this code, I notice that no slots are called and I don't see any FTP packets in my wireshark capture. In every example code I saw that's the way QFtp is used, what am I missing?
Found the issue, that wasn't immediate for a qt newbie, it didn't show any info.
I had to run QFtp in a QApplication. I think this is needed by the event loop
calling QApplication in main() solved it.
Related
Data Appending Problem While sending the data through Namedpipe using QT
localserver.h
#ifndef LOCALSERVER_H
#define LOCALSERVER_H
#include "QLocalSocket"
#include "QLocalServer"
class QLocalSocket;
class LocalServer : public QLocalServer
{
Q_OBJECT
public:
explicit LocalServer(QObject *parent = 0);
void send(QString &msj);
QLocalSocket *mSocket;
private slots:
void receive();
private:
};
#endif // LOCALSERVER_H
localserver.cpp
#include "localserver.h"
#include "QLocalSocket"
#include "QTextStream"
#include "QMessageBox"
LocalServer::LocalServer(QObject *parent) : QLocalServer(parent)
{
mSocket = nullptr;
connect(this,&LocalServer::newConnection,[&](){
mSocket = nextPendingConnection();
});
qDebug()<<"Hello World";
}
void LocalServer::send(QString &msj)
{
qDebug()<<"Sending Data";
if(mSocket)
{
QTextStream T(mSocket);
T<<msj.toStdString().c_str();
mSocket->flush();
}
}
void LocalServer::receive()
{
qDebug()<<"Im here";
QDataStream in(mSocket);
in.setVersion(QDataStream::Qt_5_2);
mSocket->readAll();
qDebug()<<"Data Received";
}
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include "QProcess"
#include "QTimer"
#include "QLocalSocket"
#include "localserver.h"
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
void Connection();
private slots:
void on_start_clicked();
void on_send_clicked();
void on_quit_clicked();
void detect_connection();
void connect_terminate();
void connected();
void send_data();
void receive_data();
QString RandomData();
void on_pbtn_Stop_clicked();
private:
Ui::Widget *ui;
LocalServer *mLocalServer;
QTimer *timer;
QLocalSocket *mSocket;
bool first;
QString data_received;
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include "QProcess"
#include "QDebug"
#include "localserver.h"
#include "QMessageBox"
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
Connection();
first = true;
}
void Widget::Connection()
{
mLocalServer = new LocalServer(this);
mLocalServer->listen("Server1");
connect(mLocalServer,SIGNAL(newConnection()),this,SLOT(detect_connection()));
first = true;
timer = new QTimer(this);
timer->setInterval(8);
connect(timer,SIGNAL(timeout()),this,SLOT(send_data()));
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_start_clicked()
{
timer->start();
}
void Widget::on_send_clicked()
{
timer->stop();
}
void Widget::on_quit_clicked()
{
timer->stop();
this->close();
}
void Widget::detect_connection()
{
qDebug()<<"Write Pipe Established";
mSocket = new QLocalSocket(this);
mSocket->connectToServer("Server2");
connect(mSocket,SIGNAL(disconnected()),this,SLOT(connect_terminate()));
connect(mSocket,SIGNAL(connected()),this,SLOT(connected()));
qDebug()<<"Connection Established, Ready to Read";
connect(mSocket,&QLocalSocket::readyRead, [&]() {
QTextStream T(mSocket);
ui->receivedText->addItem(T.readAll());
});
}
void Widget::connect_terminate()
{
qDebug()<<"Read Server Connection Terminated";
QString string = "Stop_Session";
mLocalServer->send(string);
ui->sentText->addItem(string);
}
void Widget::connected()
{
qDebug()<<"Socket Connected to Server";
QString s=" Connection Done ";
mLocalServer->send(s);
}
void Widget::send_data()
{
QString string = RandomData();
mLocalServer->send(string);
ui->sentText->addItem(string);
}
QString Widget::RandomData()
{
srand(time(NULL));
int random_number = rand()%(1920-0 + 1) + 0; // rand() return a number between 0 and RAND_MAX
int random_number1 = rand()%(1080-0 + 1) + 0;
int random_number2 = rand()%(10-0 + 1) + 0;
QString s="Contour,"+QString::number(random_number)+","+QString::number(random_number1)+","+QString::number(random_number2);
// Basically this data in "s" gives the actual contours detected data but am using a random generator to test the Local Server and Socket .
return s;
}
void Widget::receive_data()
{
QString string;
QTextStream T(mSocket);
T.readLine();
if(T.readAll()=="Stop")
{
qDebug()<<"Socket About to Close";
QString string = "Stop";
mLocalServer->send(string);
}
else
{
qDebug()<<"Program can continue"<<T.readAll();
}
}
void Widget::on_pbtn_Stop_clicked()
{
timer->stop();
}
At Receiver SIde Program
Receiver.cpp
void Receiver ::Declaration_Of_Server2()
{
// Declaration Of LocalServer i.e Server2
ServerIS = new LocalServer(this);
ServerIS->listen("Server2");
// Connect To a LocalSocket TO The Above LocalServer i.e Server_IS with Server_VS
connect(ServerIS,SIGNAL(newConnection()),this,SLOT(DetectConnection_WithServer1()));
}
void CoFire_MainPage::DetectConnection_WithServer1()
{
// Declaration of LocalSocket i.e Server_VS
SocketIS = new QLocalSocket(this);
SocketIS->connectToServer("Server1");
connect(SocketIS,SIGNAL(readyRead()),this,SLOT(Receiving_VS_Data()));
}
void CoFire_MainPage::Receiving_VS_Data()
{
// Receiving Vs Data From Socket "Socket_IS"
QTextStream msg(SocketIS);
QString str = msg.readLine();
qDebug()<<" VS DATA : "<<str;
}
By this am trying to send data ( example : Contour,1000,800,1 ) from one program to other program
with a speed of 1 data / 8msec but in real scenario it might even go to 1msec data transfer.
but by this at receving end every now and then incomming data is been appended
(example: Contour,1000,800,1Contour,200,400,1Contour,500,650,1 etc... ).
But actually expentected data is
1st
Contour,1000,800,1
next
Contour,200,400,1
next
Contour,500,650,1
etc....
This way the data is getting appeneded before i capture and process the data at receiver .
By this am loosing the precious information .
how do i solve this issue .
readLine() waits for an end-of-line ("\n" or "\r\n"), but in your case you do not send it, you must change to the following:
QString Widget::RandomData(){
srand(time(NULL));
int random_number = rand()%(1920-0 + 1) + 0; // rand() return a number between 0 and RAND_MAX
int random_number1 = rand()%(1080-0 + 1) + 0;
int random_number2 = rand()%(10-0 + 1) + 0;
return QString("Contour,%1,%2,%3\n")
.arg(random_number)
.arg(random_number1)
.arg(random_number2);
}
On the other hand it is not necessary to use the reference of the QString, and also it is unnecessary to use toStdString().c_str().
void LocalServer::send(const QString &msj)
{
qDebug()<<"Sending Data";
if(mSocket)
{
QTextStream T(mSocket);
T << msj;
mSocket->flush();
}
}
I try to get serial communication working, but struggle at waiting for the response. The logic should be to send data, wait for a response, get the response and then repeat.
To speed up my code and preventing it from blocking other independent parts of the code I run the serial communication in a separate thread.
The problem is in the send function, where I always get a "Timeout" message instead of an "Success" message.
serial.h
#ifndef SERIAL_H
#define SERIAL_H
#include <QThread>
#include <QDebug>
#include <QSerialPort>
#include <QSerialPortInfo>
#include <QStringList>
class Serial : public QThread
{
Q_OBJECT
public:
Serial();
bool send(QString text);
bool connectSerial();
void disconnectSerial();
signals:
void dataReceived(QByteArray receivedData);
protected:
void run();
private slots:
void onGetData();
private:
void readAngles();
QSerialPort qsp;
QSerialPortInfo qspi;
QByteArray receivedData;
};
#endif // SERIAL_H
serial.cpp
#include "serial.h"
Serial::Serial()
{
connect(&qsp, SIGNAL(readyRead()), this, SLOT(onGetData()));
}
bool Serial::send(QString text)
{
if (qsp.isWritable()) {
QByteArray buffer = text.toLatin1();
if (buffer.size() != qsp.write(buffer))
qDebug() << "Send does not work";
qsp.flush();
if(!qsp.waitForReadyRead(2500)) {
qDebug() << "Timeout";
} else {
qDebug() << "Success";
}
return true;
} else {
return false;
}
}
void Serial::onGetData()
{
qDebug() << "onGetData called";
qDebug() << qsp.readAll();
}
bool Serial::connectSerial(int port)
{
qDebug() << qspi.availablePorts().count();
for(int i=0; i<qspi.availablePorts().count(); i++) {
qDebug() << qspi.availablePorts().at(i).description();
}
qsp.setPort(qspi.availablePorts().at(port));
qsp.setBaudRate(QSerialPort::Baud9600);
qsp.setDataBits(QSerialPort::Data7);
qsp.setFlowControl(QSerialPort::NoFlowControl);
qsp.setParity(QSerialPort::NoParity);
qsp.setStopBits(QSerialPort::OneStop);
return qsp.open(QIODevice::ReadWrite);
}
/**
* #brief Disconnecting from serial port.
*/
void Serial::disconnectSerial()
{
if (qsp.isOpen()) {
qsp.close();
}
}
void Serial::readAngles()
{
send("012345");
}
My main issue is: I have a list of recognised IPs and I am carrying out Multi threaded TCP Client-Server Communication; so whenever a new connection request comes from any random client (server is constantly listening), I want to first compare that IP to the stored IP's and allow a new connection only if it is one of my recognised IP's. There can be a .txt file on hard disk or a QList or QString whichever is a better soluion.
EDIT: To make myself clear, Following is the server.cpp file I've developed so far and the errors I am confronted with at the moment.
#include "myserver.h"
#include "ioprogram.h"
#include <string>
#include <iostream>
using namespace std;
//string ClientInfo;
MyServer::MyServer(QObject *parent): QTcpServer(parent)
{
QStringList accepted_ip_list; //List of remote IPs that can be accepted in QString list format
accepted_ip_list.append("127.0.0.1"); // IPv4 local address
accepted_ip_list.append("::1"); // IPv6 local address
// Convert from QString to integer format, generating new list
foreach (const QString &ip, accepted_ip_list)
{
QHostAddress host_address(ip);
my_accepted_ip_list.append(host_address);
}
myserver = new QTcpServer(this);
connect(myserver, &QTcpServer::incomingConnection, this, &MyServer::incomingConnection);
myserver->listen(QHostAddress::Any, 1234);
}
void MyServer::startServer()
{
if(!this->listen(QHostAddress::Any,1234))
{
qDebug() << "Could not start server.";
}
else
{
qDebug() << "Listening...";
}
}
void MyServer::incomingConnection(qintptr socketDescriptor)
{
qDebug() << socketDescriptor << "Connecting...";
while (myserver->hasPendingConnections())
{
QTcpSocket *socket = myserver->nextPendingConnection();
QHostAddress host_address = socket->peerAddress();
bool contains = false;
for(int i=0; i < my_accepted_ip_list.size(); i++)
{
if(my_accepted_ip_list[i].isEqual(host_address,QHostAddress::ConvertV4MappedToIPv4))
{
contains = true;
break;
}
}
if(contains)
{
MyThread *thread = new MyThread(socketDescriptor, this);
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
thread->start();
}
else
{
socket->abort(); // Reject peer by disconnecting it
socket->deleteLater(); // Schedule the socket removal from memory
}
}
}
And here are the errors:
1) #line10 --- prototype for 'MyServer::MyServer(QObject*)' does not match any in class 'MyServer'
2) #line55 --- class 'QHostAddress' has no member named 'isEqual'
3) #line55 --- 'ConvertV4MappedToIPv4' is not a member of 'QHostAddress'
and here is the header file:
#ifndef MYSERVER_H
#define MYSERVER_H
#include <QTcpServer>
#include <QDebug>
#include "mythread.h"
//#include "ioprogram.h"
class MyServer : public QTcpServer
{
Q_OBJECT
public:
explicit MyServer(QTcpServer *parent = nullptr);
void startServer();
signals:
private slots:
// void newConnection();
private:
QTcpServer *myserver;
QList<QHostAddress> my_accepted_ip_list; //List of IPv4 addresses allowed by the server, in quint32 not QString
protected:
void incomingConnection(qintptr socketDescriptor);
};
#endif // MYSERVER_H
and here is one error in the header file:
candidates are: MyServer::MyServer(MyServer&&)
If i'm correct, you're looking for peerAddress with gives to you a QHostAddress.
Simple example of how to accept and reject peers:
EDIT: Since you're using the IP as a security resource, i suggest you use QSslSocket for encryption and authenticity. And contact some security expert, that i am not ;)
EDIT2: Added support for IPv6 comparison.
EDIT3: Modified method of comparison.
Header example (myserver.h file):
#ifndef MYSERVER_H
#define MYSERVER_H
#include <QTcpServer>
#include <QTcpSocket>
#include <QDebug>
class MyServer : public QTcpServer
{
Q_OBJECT
public:
explicit MyServer(QObject *parent = nullptr);
void startServer();
private:
QList<QHostAddress> my_accepted_ip_list; //List of addresses allowed by the server, in QHostAddress not QString
protected:
void incomingConnection(qintptr socketDescriptor);
};
#endif // MYSERVER_H
CPP file example (myserver.cpp file):
#include "myserver.h"
MyServer::MyServer(QObject *parent) : QTcpServer(parent)
{
QStringList accepted_ip_list; //List of remote IPs that can be accepted in QString list format
accepted_ip_list.append("127.0.0.1"); // IPv4 local address
accepted_ip_list.append("::1"); // IPv6 local address
// Convert from QString to QHostAddress format, generating new list
foreach (const QString &ip, accepted_ip_list)
{
QHostAddress host_address(ip);
my_accepted_ip_list.append(host_address);
}
}
void MyServer::startServer()
{
if (!listen(QHostAddress::Any, 1234))
{
qDebug() << "Could not start server.";
}
else
{
qDebug() << "Listening...";
}
}
void MyServer::incomingConnection(qintptr socketDescriptor)
{
QTcpSocket *socket = new QTcpSocket(this);
socket->setSocketDescriptor(socketDescriptor);
QHostAddress host_address = socket->peerAddress();
quint32 ipv4 = host_address.toIPv4Address();
QByteArray ipv6 = QByteArray((char*)host_address.toIPv6Address().c, 16);
bool contains = false;
for (int i = 0; i < my_accepted_ip_list.size(); i++)
{
quint32 accepted_ipv4 = my_accepted_ip_list[i].toIPv4Address();
QByteArray accepted_ipv6 = QByteArray((char*)my_accepted_ip_list[i].toIPv6Address().c, 16);
if (accepted_ipv4 == ipv4 || accepted_ipv6 == ipv6)
{
contains = true;
break;
}
}
if (contains)
{
qDebug() << qPrintable(socket->peerAddress().toString()) << "Accepted";
}
else
{
qDebug() << qPrintable(socket->peerAddress().toString()) << "Rejected";
socket->abort(); // Reject peer by disconnecting it
socket->deleteLater(); // Schedule the socket removal from memory
}
}
I created a small server/client application, and for testing I put the server/client function into a separate application.
The main client functions are
Client::Client(QString purpose) : networkSession(0)
{
Client::purpose = purpose;
tcpSocket = new QTcpSocket;
Client::blockSize = 0;
connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(readData()));
connect(tcpSocket, SIGNAL(error(QAbstractSocket::SocketError)),
this, SLOT(displayError(QAbstractSocket::SocketError)));
QNetworkConfigurationManager manager;
if (manager.capabilities() & QNetworkConfigurationManager::NetworkSessionRequired)
{
// Get saved network configuration
QSettings settings(QSettings::UserScope, QLatin1String("QtProject"));
settings.beginGroup(QLatin1String("QtNetwork"));
const QString id = settings.value(QLatin1String("DefaultNetworkConfiguration")).toString();
settings.endGroup();
// If the saved network configuration is not currently discovered use the system default
QNetworkConfiguration config = manager.configurationFromIdentifier(id);
if ((config.state() & QNetworkConfiguration::Discovered) !=
QNetworkConfiguration::Discovered) {
config = manager.defaultConfiguration();
}
networkSession = new QNetworkSession(config, this);
connect(networkSession, SIGNAL(opened()), this, SLOT(sessionOpened()));
}
qDebug() << "Client set up, waiting";
}
void Client::connectToServer(QString ipAddr, quint32 port)
{
qDebug() << "Connecting to Host on port " << port << ' ' << (quint16)port;
tcpSocket->connectToHost(ipAddr, port);
emit this->connectionResult((tcpSocket->state() == QAbstractSocket::UnconnectedState)?false:true);
if (tcpSocket->waitForConnected(1000))
qDebug("Connected!");
qDebug() << "Am I connected" << tcpSocket->state();
std::cout << "Am I not connected" << tcpSocket->state();
}
and the server-functions:
Server::Server(QString ipAddr, quint32 port, QString purpose)
: tcpServer(0), networkSession(0)
{
Server::clientConnection = NULL;
Server::purpose = purpose;
Server::port = port;
QNetworkConfigurationManager manager;
if (manager.capabilities() & QNetworkConfigurationManager::NetworkSessionRequired) {
// Get saved network configuration
QSettings settings(QSettings::UserScope, QLatin1String("QtProject"));
settings.beginGroup(QLatin1String("QtNetwork"));
const QString id = settings.value(QLatin1String("DefaultNetworkConfiguration")).toString();
settings.endGroup();
// If the saved network configuration is not currently discovered use the system default
QNetworkConfiguration config = manager.configurationFromIdentifier(id);
if ((config.state() & QNetworkConfiguration::Discovered) !=
QNetworkConfiguration::Discovered) {
config = manager.defaultConfiguration();
}
networkSession = new QNetworkSession(config, this);
connect(networkSession, SIGNAL(opened()), this, SLOT(sessionOpened()));
//statusLabel->setText(tr("Opening network session."));
networkSession->open();
} else {
sessionOpened();
}
//connect(tcpServer, SIGNAL(newConnection()), this, SLOT(sendFortune()));
connect(tcpServer, SIGNAL(newConnection()), this, SLOT(openNewConnection()));
//connect(tcpServer, &QTcpServer::newConnection, this, &Server::openNewConnection);
}
void Server::sessionOpened()
{
// Save the used configuration
if (networkSession) {
QNetworkConfiguration config = networkSession->configuration();
QString id;
if (config.type() == QNetworkConfiguration::UserChoice)
id = networkSession->sessionProperty(QLatin1String("UserChoiceConfiguration")).toString();
else
id = config.identifier();
QSettings settings(QSettings::UserScope, QLatin1String("QtProject"));
settings.beginGroup(QLatin1String("QtNetwork"));
settings.setValue(QLatin1String("DefaultNetworkConfiguration"), id);
settings.endGroup();
}
tcpServer = new QTcpServer(this);
if (!tcpServer->listen(QHostAddress::Any, Server::port)) {
return;
}
qDebug() << "Server listening on: " << tcpServer->serverPort();
//! [0]
QString ipAddress;
QList<QHostAddress> ipAddressesList = QNetworkInterface::allAddresses();
// use the first non-localhost IPv4 address
for (int i = 0; i < ipAddressesList.size(); ++i) {
if (ipAddressesList.at(i) != QHostAddress::LocalHost &&
ipAddressesList.at(i).toIPv4Address()) {
ipAddress = ipAddressesList.at(i).toString();
break;
}
}
// if we did not find one, use IPv4 localhost
if (ipAddress.isEmpty())
ipAddress = QHostAddress(QHostAddress::LocalHost).toString();
//! [1]
}
void Server::openNewConnection(void)
{
qDebug() << "New conn incoming!";
Server::clientConnection = tcpServer->nextPendingConnection();
QVariant ipAddr_QVar(clientConnection->peerAddress().toString());
qDebug() << "Got new connection!";
emit gotNewConnection(ipAddr_QVar);
}
The main problem here is that even if I get a "Connected" from
if (tcpSocket->waitForConnected(1000))
qDebug("Connected!");
qDebug() << "Am I connected" << tcpSocket->state();
in the client function, but the server function openNewConnection() never gets called. Why? How can I find the bug?
If a minimal working example is necessary, I can provide the whole code, but here I just wanted to provide the most important functions.
Edit:
client.h:
#ifndef CLIENT_H
#define CLIENT_H
//#include <QDialog>
#include <iostream>
#include <QTcpSocket>
class QComboBox;
class QDialogButtonBox;
class QLabel;
class QLineEdit;
class QPushButton;
class QTcpSocket;
class QNetworkSession;
class Client : public QObject
{
Q_OBJECT
private:
QTcpSocket *tcpSocket;
QString currentFortune;
quint16 blockSize;
QPair<QString, QPair<QString, QVariant> > data;
QNetworkSession *networkSession;
QString purpose;
signals:
void gotData(QPair<QString, QPair<QString, QVariant> >);
void noConnection(void);
void connectionResult(bool);
void isDisconnect(bool);
public slots:
void displayError(QAbstractSocket::SocketError socketError);
void sessionOpened();
void getInfo();
void readData();
void connectToServer(QString ipAddr, quint32 port);
void disconnectFromServer();
private:
public:
Client(QString purpose);
};
#endif // CLIENT_H
server.h:
#ifndef SERVER_H
#define SERVER_H
#include <QTcpServer>
#include <iostream>
//#include <QtTest/QTest>
#include <QSignalSpy>
#include <QTcpSocket>
#include <QDebug>
//#include <QMessageBox>
#include <QNetworkInterface>
#include <typeinfo>
#include <QStringList>
//#include <QSignalSpy>
QT_BEGIN_NAMESPACE
class QTcpServer;
class QNetworkSession;
QT_END_NAMESPACE
class Server : public QObject
{
Q_OBJECT
public slots:
void sessionOpened();
void sendFortune(void);
void sendData(QPair<QString, QPair<QString, QVariant> > data);
void sendFile(QVariant fileName);
void disconnectServer(void);
void openNewConnection(void);
signals:
void gotNewConnection(QVariant);
private:
QString purpose;
QTcpServer *tcpServer;
QString ipAddr;
quint32 port;
QTcpSocket *clientConnection;
quint32 BlockSize;
bool firstTime;
QSignalSpy * m_pSignalSpy;
QStringList fortunes;
QNetworkSession *networkSession;
//QNetworkConfiguration config;
public:
Server(QString ipAddr, quint32 port, QString purpose = "");
};
#endif // SERVER_H
The problem lies with your QNetworkSession, you have declared it in scope. Meaning once you leave that function the QNetworkSession gets destroyed. A destroyed object cannot emit a signal. Maybe make it a member variable or construct it in your header.
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();
}