How to send a File with Qt
-
Hello Everyone,
First of all i want to thank the Qt Community for the great Content of this forum. I'm a Qt newbie and I'm working on a little Qt Application that transfers one File from my Computer to another Computer.
I did some research and ended up writing this Code
Client::Client(QObject *parent) : QObject(parent) { } void Client::Upload() { QString ZFsolutionFolder = "C:\\Users\\X240\\Desktop\\Masterarbeit\\ZF-Schulungssystem\\ZF-Schulungssystem\\TwinCAT\\"; QString ZFsolutionName = "TwinCAT_Virtuos_Testprojekt_VirtuosIOWizard@1"; //Creating the Socket Object socket = new QTcpSocket(this); //Setting the IP Adress to the Target System. Will later be set through User Input QString HostAdress = "192.168.10.10"; printf(QString("Connection to Host under " + HostAdress + " started\n").toStdString().c_str()); //Connecting to the Hose socket->connectToHost(HostAdress, 8016); if (!socket->waitForConnected(5000)) //Checking if the Connection is established { printf("Connection to Host failed\n"); } else { printf(QString("Connected to " + HostAdress + " successfully\n").toStdString().c_str()); printf("checking if the configuration exists\n"); QFile TCFile(ZFsolutionFolder + ZFsolutionName + ".sln"); //Opening the Local File that will be sent if (!TCFile.exists()) { printf(QString(ZFsolutionName + " does not exist\n").toStdString().c_str()); } else { printf("file exists. Opening...\n"); TCFile.open(QIODevice::ReadOnly); } QByteArray q = TCFile.readAll(); socket->write(q); } }
If my Code is right, it connects to the Host under the given Ip Address and writes the local File to the Socket. The next Step would be to make the Code that reads the File from the Socket and saves it to a given Path on the Target Computer. That's where i'm stuck at the moment.
Can anyone give me any hints or recommend any examples on how to accomplish this?
Every tip is welcome !! Thanks !!
-
Hello Everyone,
First of all i want to thank the Qt Community for the great Content of this forum. I'm a Qt newbie and I'm working on a little Qt Application that transfers one File from my Computer to another Computer.
I did some research and ended up writing this Code
Client::Client(QObject *parent) : QObject(parent) { } void Client::Upload() { QString ZFsolutionFolder = "C:\\Users\\X240\\Desktop\\Masterarbeit\\ZF-Schulungssystem\\ZF-Schulungssystem\\TwinCAT\\"; QString ZFsolutionName = "TwinCAT_Virtuos_Testprojekt_VirtuosIOWizard@1"; //Creating the Socket Object socket = new QTcpSocket(this); //Setting the IP Adress to the Target System. Will later be set through User Input QString HostAdress = "192.168.10.10"; printf(QString("Connection to Host under " + HostAdress + " started\n").toStdString().c_str()); //Connecting to the Hose socket->connectToHost(HostAdress, 8016); if (!socket->waitForConnected(5000)) //Checking if the Connection is established { printf("Connection to Host failed\n"); } else { printf(QString("Connected to " + HostAdress + " successfully\n").toStdString().c_str()); printf("checking if the configuration exists\n"); QFile TCFile(ZFsolutionFolder + ZFsolutionName + ".sln"); //Opening the Local File that will be sent if (!TCFile.exists()) { printf(QString(ZFsolutionName + " does not exist\n").toStdString().c_str()); } else { printf("file exists. Opening...\n"); TCFile.open(QIODevice::ReadOnly); } QByteArray q = TCFile.readAll(); socket->write(q); } }
If my Code is right, it connects to the Host under the given Ip Address and writes the local File to the Socket. The next Step would be to make the Code that reads the File from the Socket and saves it to a given Path on the Target Computer. That's where i'm stuck at the moment.
Can anyone give me any hints or recommend any examples on how to accomplish this?
Every tip is welcome !! Thanks !!
@JohnSRV
For the server side, you might like to look through the https://doc.qt.io/qt-5/qtnetwork-fortuneserver-example.html example, though your situation might be a bit simpler.You will kind of do the reverse from your client here: read the bytes arriving on the socket, write them to a file. The only "wriggle" is you won't be able to get with a single
socket->readAll()
where you have s singlesocket->write()
in your client. You will need to use signals & slots, to save data as it arrives. -
@JohnSRV
For the server side, you might like to look through the https://doc.qt.io/qt-5/qtnetwork-fortuneserver-example.html example, though your situation might be a bit simpler.You will kind of do the reverse from your client here: read the bytes arriving on the socket, write them to a file. The only "wriggle" is you won't be able to get with a single
socket->readAll()
where you have s singlesocket->write()
in your client. You will need to use signals & slots, to save data as it arrives.@JonB hey thanks for your answer.
So I implemented the server side. Here's the header File to the Server:#ifndef SERVER_H #define SERVER_H #include <QObject> #include <QTcpSocket> #include <QAbstractSocket> #include <QDataStream> #include <QTcpServer> #include <QHostAddress> #include <QDialog> #include <QLabel> #include "SocketThread.h" class Server : public QTcpServer { Q_OBJECT public: explicit Server(QHostAddress host = QHostAddress::Any, quint16 port = 8016, QObject *parent = 0); ~Server(); void incomingConnection(qintptr handle) Q_DECL_OVERRIDE; signals: public slots: void start(); private: QHostAddress m_host; quint16 m_port; }; #endif
and the Server.cpp
#include "Server.h" #include <QFile> #include "moc_Server.cpp" #include <QMessageBox> #include <QList> #include <QNetworkInterface> #include "SocketThread.h" Server::Server(QHostAddress host, quint16 port, QObject *parent) : QTcpServer(parent), m_host(host), m_port(port) { } Server::~Server() { printf("~Server"); } void Server::start() { QHostAddress pHost; pHost.setAddress("192.168.10.10"); //Setting the Address of the Server to the Address of the target system QString printAddress; printAddress = pHost.toString(); if (this->listen(QHostAddress::Any, 8016)) { printf(QString("Server started at " + printAddress+ "and Listening \n").toStdString().c_str()); } else { printf("Server could not be started \n"); } }
void Server::incomingConnection(qintptr handle) { printf("incoming Connection"); SocketThread *thread = new SocketThread(handle); connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
thread->start(); //this jumps directly to the run function in the socket thread.
}
I implemented the Thread as following:
#include "SocketThread.h" #include "moc_SocketThread.cpp" #include <Qt> #include <QFile> #include "Client.h" SocketThread::SocketThread(qintptr descriptor, QObject *parent) : QThread(parent), m_socketDescriptor(descriptor), m_blockSize(0) { } SocketThread::~SocketThread() { delete m_socket; } void SocketThread::run() { m_socket = new QTcpSocket; m_socket->setSocketDescriptor(m_socketDescriptor); connect(m_socket, SIGNAL(readyread()), this, SLOT(onReadyRead()), Qt::DirectConnection); connect(m_socket, SIGNAL(disconnected()), this, SLOT(onDisconnected()), Qt::DirectConnection); exec(); //this keeps the thread running. Otherwise it will end automatically } void SocketThread::onReadyRead() { QString fileName; //String for the file name fileName = "TwinCAT_Virtuos_Testprojekt_VirtuosIOWizard@1"; QByteArray line = m_socket->readAll(); //reading Data from the Socket and returning it as a byte array QString FilePath = "C:\\test"; // hier the Path on the receiving End QFile target(FilePath + "/" + fileName); if (!target.open(QIODevice::WriteOnly)) { //opening the File to write the incoming Data to it printf("can't open File for writing"); } target.write(line); //Writing the byte Array line to the target file target.close(); emit onFinishRecieved(); m_socket->disconnectFromHost(); } void SocketThread::onDisconnected() { m_socket->close(); quit(); }
The Server starts successfully and is listening. The clients connects with Data to write. The Problem is that the function incomingConnection(qintptr handle) is not executed. What am I missing??
Any hint is highly appreciated. Thanks !
-
@JonB hey thanks for your answer.
So I implemented the server side. Here's the header File to the Server:#ifndef SERVER_H #define SERVER_H #include <QObject> #include <QTcpSocket> #include <QAbstractSocket> #include <QDataStream> #include <QTcpServer> #include <QHostAddress> #include <QDialog> #include <QLabel> #include "SocketThread.h" class Server : public QTcpServer { Q_OBJECT public: explicit Server(QHostAddress host = QHostAddress::Any, quint16 port = 8016, QObject *parent = 0); ~Server(); void incomingConnection(qintptr handle) Q_DECL_OVERRIDE; signals: public slots: void start(); private: QHostAddress m_host; quint16 m_port; }; #endif
and the Server.cpp
#include "Server.h" #include <QFile> #include "moc_Server.cpp" #include <QMessageBox> #include <QList> #include <QNetworkInterface> #include "SocketThread.h" Server::Server(QHostAddress host, quint16 port, QObject *parent) : QTcpServer(parent), m_host(host), m_port(port) { } Server::~Server() { printf("~Server"); } void Server::start() { QHostAddress pHost; pHost.setAddress("192.168.10.10"); //Setting the Address of the Server to the Address of the target system QString printAddress; printAddress = pHost.toString(); if (this->listen(QHostAddress::Any, 8016)) { printf(QString("Server started at " + printAddress+ "and Listening \n").toStdString().c_str()); } else { printf("Server could not be started \n"); } }
void Server::incomingConnection(qintptr handle) { printf("incoming Connection"); SocketThread *thread = new SocketThread(handle); connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
thread->start(); //this jumps directly to the run function in the socket thread.
}
I implemented the Thread as following:
#include "SocketThread.h" #include "moc_SocketThread.cpp" #include <Qt> #include <QFile> #include "Client.h" SocketThread::SocketThread(qintptr descriptor, QObject *parent) : QThread(parent), m_socketDescriptor(descriptor), m_blockSize(0) { } SocketThread::~SocketThread() { delete m_socket; } void SocketThread::run() { m_socket = new QTcpSocket; m_socket->setSocketDescriptor(m_socketDescriptor); connect(m_socket, SIGNAL(readyread()), this, SLOT(onReadyRead()), Qt::DirectConnection); connect(m_socket, SIGNAL(disconnected()), this, SLOT(onDisconnected()), Qt::DirectConnection); exec(); //this keeps the thread running. Otherwise it will end automatically } void SocketThread::onReadyRead() { QString fileName; //String for the file name fileName = "TwinCAT_Virtuos_Testprojekt_VirtuosIOWizard@1"; QByteArray line = m_socket->readAll(); //reading Data from the Socket and returning it as a byte array QString FilePath = "C:\\test"; // hier the Path on the receiving End QFile target(FilePath + "/" + fileName); if (!target.open(QIODevice::WriteOnly)) { //opening the File to write the incoming Data to it printf("can't open File for writing"); } target.write(line); //Writing the byte Array line to the target file target.close(); emit onFinishRecieved(); m_socket->disconnectFromHost(); } void SocketThread::onDisconnected() { m_socket->close(); quit(); }
The Server starts successfully and is listening. The clients connects with Data to write. The Problem is that the function incomingConnection(qintptr handle) is not executed. What am I missing??
Any hint is highly appreciated. Thanks !
@JohnSRV
I don't know, but you could compare your threaded example to the accepted solution in https://stackoverflow.com/questions/31720030/qt-qtcpserverincomingconnectionqintptr-handle-not-firing.There is also https://www.bogotobogo.com/Qt/Qt5_QTcpServer_Multithreaded_Client_Server.php.
You should also look at https://stackoverflow.com/questions/39085195/qtcpserverincomingconnectionqintptr-not-calling. It looks similar to yours. However, I note --- I think --- that the
listen()
is done in the main thread and a new thread is only spawned after a connection has been received.I know no more than the above.
-
@JohnSRV
I don't know, but you could compare your threaded example to the accepted solution in https://stackoverflow.com/questions/31720030/qt-qtcpserverincomingconnectionqintptr-handle-not-firing.There is also https://www.bogotobogo.com/Qt/Qt5_QTcpServer_Multithreaded_Client_Server.php.
You should also look at https://stackoverflow.com/questions/39085195/qtcpserverincomingconnectionqintptr-not-calling. It looks similar to yours. However, I note --- I think --- that the
listen()
is done in the main thread and a new thread is only spawned after a connection has been received.I know no more than the above.