QTcpServer -- how to stop client threads - qt

My gui have a two button's, one to start a server & other to stop a server.
Brief :---
Once server is started, on every new client request i will create a new thread & this will handle communication with the client.
Detail :--
When start button is pressed, I am creating an object 'tcpserverobjectWrapper' which creates an another object 'tcpserverobject' this object creats an Qtcpserver.
Now this Qtcpserver is listing for new connection. And when a new connection comes i create an 'TcpSocketThreadWrapperObject' object which
creates a thread & this thread handles communication with client . Also 'tcpserverobject' keeps the list of new client request objects created
'QList<TcpSocketThreadWrapperObject *> TcpSocketThreadWrapperObjectList;' .
I am able to connect to server from telnet clients & it creates new thread for each client & works fine.
When stop button pressed i am able to stop server & client threads.
But i have two problems here :---
1> Everytime client send some data to server. I get this kind of QsocketNotifier. What is this ?
QSocketNotifier: socket notifiers cannot be enabled from another thread
QSocketNotifier: socket notifiers cannot be disabled from another thread
2> If i press stop button on GUI i am able to stop the threads succesfully.
But how to stop the threads & delete the objects created for every client when client send 'STOP command' to server or closes the connection with server ?
I will also have to delete the following objects created on each client request ?
client request --> TcpSocketThreadWrapperObject -- creates --> TcpSocketThreadObject -- creates --> TcpSocketThreadObject
Can someone suggest how to solve above two problems ? Reply on this will be appreciated.
Here is the code :---
================= start & stop buttons handler =====
void MainWindow::on_actionStop_triggered()
{
if(b_threadAlreadyStarted)
{
/* ------------------ Tcp server object ------------------------*/
b_threadAlreadyStarted = false;
delete p_tcpserverobjectWrapper;
/* ------------------ Tcp server object ------------------------*/
}
}
void MainWindow::on_actionStart_triggered()
{
if(!b_threadAlreadyStarted)
{
/* ------------------ Tcp server object ------------------------*/
b_threadAlreadyStarted =true;
p_tcpserverobjectWrapper = new tcpserverobjectWrapper(this,modelCANalyzer);
qDebug() << " \n start ";
/* ------------------ Tcp server object ------------------------*/
}
}
======== tcpserverobjectWrapper class ===============
// Main server object wrapper
class tcpserverobjectWrapper : public QObject
{
Q_OBJECT
public:
explicit tcpserverobjectWrapper(QMainWindow *ptrWidget, QStandardItemModel *modelCANalyzer, QObject *parent=0);
~tcpserverobjectWrapper();
//Device thread object
tcpserverobject *m_tcpserverobject;
};
tcpserverobjectWrapper::tcpserverobjectWrapper(QMainWindow *ptrWidget , QStandardItemModel *modelCANalyzer,QObject *parent) :
QObject(parent)
{
m_tcpserverobject = new tcpserverobject ;
//save model
m_tcpserverobject->modeltable = modelCANalyzer;
m_tcpserverobject->ptrmainwindow = ptrWidget;
qDebug() << "\n tcp server thread started";
}
tcpserverobjectWrapper::~tcpserverobjectWrapper()
{
qDebug() << " \n called delete later on tcpserverobjectWrapper .. !!";
m_tcpserverobject->deleteLater(); // ---------------------> change it to - delete m_tcpserverobject
qDebug() << " \n tcp server object successfully quited .. !! ";
}
========== tcpserverobject object ==================
class tcpserverobject : public QObject
{
Q_OBJECT
public:
explicit tcpserverobject(QObject *parent = 0);
~tcpserverobject();
/*!
Pointer to QStandardItemModel to be used inside - canTableView
*/
QStandardItemModel *modeltable;
//mainwindow pointer
QMainWindow *ptrmainwindow;
// Create list of new -- socket thread wrapper objects
QList<TcpSocketThreadWrapperObject *> TcpSocketThreadWrapperObjectList;
private:
QTcpServer *tcpServer;
signals:
public slots:
void on_newConnection();
};
tcpserverobject::tcpserverobject(QObject *parent) :
QObject(parent), tcpServer(0)
{
tcpServer = new QTcpServer;
// Connect slot of the server
connect(tcpServer, SIGNAL(newConnection()), this, SLOT(on_newConnection()));
//lisen on socket
if (!tcpServer->listen(QHostAddress::LocalHost, SERVER_PORT )) {
qDebug() << "\n returning from server listning error .. !!! ";
return;
}
qDebug() << "\n server listning";
}
tcpserverobject::~tcpserverobject()
{
// to do
while (!TcpSocketThreadWrapperObjectList.isEmpty())
delete TcpSocketThreadWrapperObjectList.takeFirst();
}
void tcpserverobject::on_newConnection()
{
QByteArray block;
block.append(" \n Hello from server .. !!!") ;
QTcpSocket *clientConnection = tcpServer->nextPendingConnection();
connect(clientConnection, SIGNAL(disconnected()),
clientConnection, SLOT(deleteLater()));
// Create new thread for this .. client request ..!!
qDebug() << "\n New connection request ..!!!";
qDebug() << "\n New client from:" << clientConnection->peerAddress().toString();
clientConnection->write(block);
clientConnection->flush();
// create new tcp object
TcpSocketThreadWrapperObject* TcpSocketThreadWrapperObjectPtr = new TcpSocketThreadWrapperObject(clientConnection);
// Append object to the list
TcpSocketThreadWrapperObjectList.append(TcpSocketThreadWrapperObjectPtr);
}
============ TcpSocketThreadWrapperObject ==============
// Main device thread object
class TcpSocketThreadWrapperObject : public QObject
{
Q_OBJECT
public:
explicit TcpSocketThreadWrapperObject(QTcpSocket *m_pTcpSocket , QObject *parent = 0);
~TcpSocketThreadWrapperObject();
/*!
pointer for write thread
*/
QThread m_TcpSocketRWThread;
/// pointer to the socketthread object
class TcpSocketThreadObject *m_pTcpSocketThreadObject;
signals:
public slots:
};
// constructor for the deviceThreadObject
TcpSocketThreadWrapperObject::TcpSocketThreadWrapperObject(QTcpSocket *m_pTcpSocket , QObject *parent) :
QObject(parent)
{
m_pTcpSocketThreadObject = new TcpSocketThreadObject(m_pTcpSocket);
//set flag for event loop -- make while(1)
m_pTcpSocketThreadObject->m_bQuit = false;
// connect the signal & slot
connect(&m_TcpSocketRWThread,SIGNAL(started()),m_pTcpSocketThreadObject,SLOT(dowork_socket()));
// Move thread to object
m_pTcpSocketThreadObject->moveToThread(&m_TcpSocketRWThread);
//Start the thread
m_TcpSocketRWThread.start();
}
TcpSocketThreadWrapperObject::~TcpSocketThreadWrapperObject()
{
//set flag for event loop -- make while(0)
m_pTcpSocketThreadObject->m_bQuit = false;
// Wait for the thread to terminate
m_TcpSocketRWThread.quit();
m_TcpSocketRWThread.wait();
// Delete the object
m_pTcpSocketThreadObject->deleteLater();
qDebug() << "\n deleted - TcpSocketThreadWrapperObject";
}
======== TcpSocketThreadObject object ========
class TcpSocketThreadObject : public QObject
{
Q_OBJECT
public:
explicit TcpSocketThreadObject(QTcpSocket *m_pTcpSocketTemp , QObject *parent = 0);
~TcpSocketThreadObject();
/*!
Pointer to TCP socket -- created by the server
*/
QTcpSocket *m_pclientConnectionSocket;
/*!
Termination control main thread
*/
volatile bool m_bQuit;
signals:
public slots:
void dowork_socket();
};
// constructor for the deviceThreadObject
TcpSocketThreadObject::TcpSocketThreadObject(QTcpSocket *m_pTcpSocketTemp , QObject *parent) :
QObject(parent)
{
m_pclientConnectionSocket = m_pTcpSocketTemp;
// todo
}
TcpSocketThreadObject::~TcpSocketThreadObject()
{
// todo
}
void TcpSocketThreadObject::dowork_socket()
{
QByteArray block;
block.append(" \n hi again .. !!!") ;
// Write to socket
m_pclientConnectionSocket->write(block);
m_pclientConnectionSocket->flush();
// Close socket
m_pclientConnectionSocket->disconnectFromHost();
qDebug() << "\n entring loop of socket thread ..!!!";
while(!m_bQuit)
{
// while loop --> send/rx command from client
}
}
======= output of one client connected to server =====
New connection request ..!!!
New client from: "127.0.0.1"
QSocketNotifier: socket notifiers cannot be enabled from another thread
QSocketNotifier: socket notifiers cannot be disabled from another thread
entring loop of socket thread ..!!!

I think the simplest solution to all of this is to stop using QThread.
QTcpSocket and QTcpServer are both asynchronous, so when you receive a connection, you only need to create a class to wrap the QTcpSocket and this class handles the reading of the data, having connected the QTcpSocket signals to the class's slots.
If you're getting a lot of connections, then you'll be creating lots of threads. More threads than processor cores is just a waste of time.
If each connection is requesting a lot of work to be done by the server, you can then create separate worker objects and move those to a different thread, but overall, I recommend that you do not use separate threads for QTcpServer and QTcpSockets.

Related

How process signals in an external thread

A external component has a callback which executes in its internal thread start with std::thread, I want to create a qt component(not UI) in this thread, connect other qt components signal to this qt component, and let the slot function execute in this internal thread.
I expect to execute to run the event loop once callback triggerd to process pending slot functions invoking.
// call in a thread start with std::thread in ExternalComponent, this method invoke periodically.
void ExternalComponent::InternalProcessing() {
//do other thing...
//invoke callback
callback();
}
void CustomQtComponent::Init() {
externalComponent.SetCallback([]() {
// first time, create a Worker
if (worker_ == nullptr) {
worker_ = new Worker();
}
// process pending signals(invoke worker_ slot methods) in this thread
// ...
// do other things.
});
}
// call by ui thread
void CustomQtComponent::DoSomething() {
// do xxxx
// ...
// emit a signal, to let something process in callback threads
// emit cutstomSignalWhichConnectToWokerSlots();
}
Because external threads not start by QThread, so though we can get the QThread object in its thread(in callback), but it has no event loop.
Could I construct a QEventLoop in callback thread, and let it receive and process signals sending to worker_?
Working example with trivial classes:
...{
std::thread([this]()
{
qDebug() << "current thread is" << QThread::currentThread();
auto recv = new Worker;
connect(this, &MainWin::call, recv, &Worker::callMe);
/* Note that recv's slots will be called in the thread where
the recv object lives */
QEventLoop eventLoop;
// Do not forget to setup exit mechanism
connect(qApp, &QApplication::aboutToQuit,
&eventLoop, &QEventLoop::quit);
// Do not forget to start the loop but only after connections
eventLoop.exec();
}).detach();
// After start the thread we can trigger the signal
QThread::msleep(1000); // make sure won't be called earlier than connect()
// Check the threads are different
qDebug() << "current thread is" << QThread::currentThread();
emit call();
}
Where
void Worker::callMe()
{
qDebug() << "callMe invoked";
qDebug() << "current thread is" << QThread::currentThread();
}
See also the list of useful links about objects, signals-slots and threading in Qt, in the answer: https://stackoverflow.com/a/60755238/4149835

Exit QThread when GUI Application exits

I have the following worker class:
class MediaWorker : public QObject
{
Q_OBJECT
public:
explicit MediaWorker(QObject *parent = 0);
~MediaWorker();
void Exit();
signals:
void Finished();
public slots:
void OnExecuteProcess();
};
In MediaWorker.cpp
void MediaWorker::Exit()
{
emit Finished();
}
void MediaWorker::OnExecuteProcess()
{
qDebug() << "Worker Thread: " << QThread::currentThreadId();
}
In my MainWindow I do the following:
this->threadMediaWorker = new QThread();
this->mediaWorker = new MediaWorker();
this->timerMediaWorker = new QTimer();
this->timerMediaWorker->setInterval(1000);
this->timerMediaWorker->moveToThread(this->threadMediaWorker);
this->mediaWorker->moveToThread(this->threadMediaWorker);
connect(this->threadMediaWorker, SIGNAL(started()), this->timerMediaWorker, SLOT(start()));
connect(this->timerMediaWorker, &QTimer::timeout, this->mediaWorker, &MediaWorker::OnExecuteProcess);
connect(this->mediaWorker, &MediaWorker::Finished, this->threadMediaWorker, &QThread::quit);
connect(this->mediaWorker, &MediaWorker::Finished, this->mediaWorker, &MediaWorker::deleteLater);
connect(this->threadMediaWorker, &QThread::finished, this->mediaWorker, &QThread::deleteLater);
this->threadMediaWorker->start();
The threading is working properly. When I close the application I terminate the thread in the destructor:
MainWindow::~MainWindow()
{
delete ui;
this->mediaWorker->Exit();
}
so Exit() emits the Finished signal which will hopefully delete the qthread and mediaworker class.
My question is if this is the proper way of terminating both the thread and media worker class?
My question is what is the proper way of terminating both the
worker thread and media worker class?
You can just ensure that the 'media' object gets deleted while the main window gets destructed by using either QScopedPointer or std::unique_ptr.
class MainWindow : public QMainWindow {
/// ...
QThread m_workerThread;
QScopedPointer<MediaWorker> m_pMediaObject;
/// ...
};
void MainWindows::init()
{
// ... other initialization skipped ...
// for dynamic allocation of the object and keeping the track of it
m_mediaObject.reset(new MediaWorker());
m_workerThread.moveToThread(m_mediaObject.data());
}
void MainWindow::stopWorker()
{
if (m_workerThread.isRunning())
{
m_workerThread.quit(); // commands Qt thread to quit its loop
// wait till the thread actually quits
m_workerThread.wait(); // possible to specify milliseconds but
// whether or not to limit the wait is
// another question
}
}
If the worker thread used for updating the UI it makes sense to attempt to stop the worker thread before the UI objects released in
void MainWindow::closeEvent(QCloseEvent *)
{
stopWorker();
}
But there is a chance that the main window never gets closeEvent() called before the destruction so we should handle that:
MainWindow::~MainWindow()
{
stopWorker();
// it also destroys m_mediaObject
}

QT QTcpServer::incomingConnection(qintptr handle) not firing?

I'm trying to create a multithreaded server using Qt for the first time. Normally one would use the socket pointer returned by the QTcpServer::nextPendingConnection() with the socket handle already baked in - but since I'm interfacing with the connecting client on a separate thread, I need to create the socket separately using the qintptr handle from QTcpServer::incomingConnection(qintptr handle). After a very dreary, error-packed debugging session I managed to track down the problem to the QTcpServer::incomingConnection() never being fired?
Has anyone had a similar problem - has something changed over recent versions Qt?
These are the ones I've tried:
QTcpServer::incomingConnection(qintptr handle)
QTcpServer::incomingConnection(qintptr socketDescriptor)
QTcpServer::incomingConnection(int handle)
EDIT:
Creating instance of server:
TestServer *myServer = new TestServer();
myServer->initializeServer(1234);
Which calls:
void TestServer::initializeServer(quint16 port)
{
mainServer = new QTcpServer(this);
mainServer->listen(QHostAddress::Any, port);
qDebug() << "Listening for connections on port: " << port;
}
Server is now listening. When a client connects incomingConnection(qintptr handle) is supposed to be called:
void TestServer::incomingConnection(qintptr socketDescriptor){
TestClient *client = new TestClient(this);
client->setSocket(socketDescriptor);
}
Which calls:
void TestClient::setSocket(quint16 socketDescr)
{
socket = new QTcpSocket(this);
socket->setSocketDescriptor(socketDescr);
connect(socket, SIGNAL(connected()),this,SLOT(connected()));
connect(socket, SIGNAL(disconnected()),this,SLOT(disconnected()));
connect(socket, SIGNAL(readyRead()),this,SLOT(readyRead()));
}
Called on connect() signal:
void TestClient::connected()
{
qDebug() << "Client connected..."; // This debug never appears in the console, since QTcpServer::incomingConnection isn't being fired.
}
You have some errors at your code:
At TestServer your QTcpServer probably aggregated, but you need to inherit it. At this case you try to override incomingConnection() method, but you haven't base class and you just create new incomingConnection(), not override.
You get qintptr descriptor variable from incomingConnection(), but set quint16 type at setSocket() method.
You probably mix client of server and client of your part, which just get incoming connection and handling socket data.
I write some little example below for your understanding tcp client-server communication.
Server part
Main part is server themselves:
#include <QTcpServer>
class TestServer: public QTcpServer
{
public:
TestServer(QObject *parent = 0);
void incomingConnection(qintptr handle) Q_DECL_OVERRIDE;
};
Just look: I don't aggragate QTcpServer, but inherited it. At this case you can override incomingConnection() method correctly.
At constructor we just start server for listening using listen() method:
TestServer::TestServer(QObject *parent):
QTcpServer(parent)
{
if (this->listen(QHostAddress::Any, 2323)) {
qDebug() << "Server start at port: " << this->serverPort();
} else {
qDebug() << "Start failure";
}
}
Then time for overriding incomingConnection():
void TestServer::incomingConnection(qintptr handle)
{
qDebug() << Q_FUNC_INFO << " new connection";
SocketThread *socket = new SocketThread(handle);
connect(socket, SIGNAL(finished()), socket, SLOT(deleteLater()));
socket->start();
}
I create SocketThread object which handle incoming data:
#include <QThread>
#include <QObject>
class QTcpSocket;
class SocketThread: public QThread
{
Q_OBJECT
public:
SocketThread(qintptr descriptor, QObject *parent = 0);
~SocketThread();
protected:
void run() Q_DECL_OVERRIDE;
private slots:
void onConnected();
void onReadyRead();
void onDisconnected();
private:
QTcpSocket *m_socket;
qintptr m_descriptor;
};
We inherits from QThread for making our server multithreading, so we have to override run() method:
SocketThread::SocketThread(qintptr descriptor, QObject *parent)
: QThread(parent), m_descriptor(descriptor)
{
}
void SocketThread::run()
{
qDebug() << Q_FUNC_INFO;
m_socket = new QTcpSocket;
m_socket->setSocketDescriptor(m_descriptor);
connect(m_socket, SIGNAL(readyRead()), this, SLOT(onReadyRead()), Qt::DirectConnection);
connect(m_socket, SIGNAL(disconnected()), this, SLOT(onDisconnected()), Qt::DirectConnection);
exec();
}
This way we initialize our QTcpSocket, set socket descriptor, connect it with readyRead() and disconnected() signals and start event loop.
void SocketThread::onReadyRead()
{
QDataStream in(m_socket);
in.setVersion(QDataStream::Qt_5_5);
QString message;
in >> message;
qDebug() << message;
m_socket->disconnectFromHost();
}
void SocketThread::onDisconnected()
{
m_socket->close();
// Exit event loop
quit();
}
At onReadyRead() just read some QString from client, write it to console and disconnect from host. At onDisconnected() we close socket connection and exit event loop.
Client part
It is just example and bad-smells style, but i create connection to the server at MainWindow class on QPushButton::clicked signal:
void MainWindow::on_pushButton_clicked()
{
QTcpSocket *client = new QTcpSocket;
connect(client, SIGNAL(connected()), this, SLOT(connected()));
connect(client, SIGNAL(disconnected()), client, SLOT(deleteLater()));
client->connectToHost(QHostAddress::LocalHost, 2323);
client->waitForConnected();
if (client->state() != QAbstractSocket::ConnectedState ) {
qDebug() << Q_FUNC_INFO << " can't connect to host";
delete client;
return;
}
QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_5_5);
out << QString("Hello");
out.device()->seek(0);
client->write(block);
}
void MainWindow::connected()
{
qDebug() << Q_FUNC_INFO << " client connected";
}
I create new QTcpSocket, connect it to the signals and try to connect to the host(in my case it is localhost). Wait for connected and check socket status. If all is right I write to socket QString - just example.
It is one of possible ways to organized multithreading client-server architecture, i hope it will be helpfull for you and you find yours bugs.

How to maintain a tcp socket in qt?

I have overloaded the incomingConnection function of QTcpServer at the server side with following code
void CtiServer::incomingConnection(int socketDescriptor)
{
qDebug() << QString("CtiServer thread id = %1, thread = %2").arg(QString::number((uint)QThread::currentThreadId(), 16)).arg(QString::number((qlonglong)QThread::currentThread(), 16));
ServerThread *thread = new ServerThread(socketDescriptor, this);
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
thread->start();
}
Then in every thread i created a new QTcpSocket subclass object named ServerSocket,
void ServerThread::run()
{
qDebug() << QString("ServerThread thread id = %1, thread = %2").arg(QString::number((uint)QThread::currentThreadId(), 16)).arg(QString::number((qlonglong)QThread::currentThread(), 16));
serverSocket = new ServerSocket();
serverSocket->setSocketDescriptor(socketDescriptor);
connect(serverSocket, SIGNAL(readyRead()), serverSocket, SLOT(handleRequest()));
serverSocket->waitForDisconnected(-1);
}
The problem is whether serverSocket->waitForDisconnected(-1) is right or not.
I am trying to maintain the socket with this statement, util client send some message to notify the server socket that the connection should be shutdown, so that I could keep a long connection between server and client.
As a result, I could connect the disconnected signal and know when the client is down without bothering to set up some heart-beat protocol to detect whether a client is still alive or dead.
Or should I set up a heart-beat protocol and use code like following:
sock.disconnectFromHost();
sock.waitForDisconnected();
instead of sock.waitForDisconnected(-1).

QTcpSocket does not send data sometimes

I have two QT apps. One app can be considered to hold a big data and it sends about 10 KB of data chunk every second to second application.
Earlier I tried using QUdpSocket to transmit the data but due to MTU limitation of about 2-5K and need to divide and reunite the data myself, I switched to QTcpSocket.
Sometimes data is sent correctly with QTcpSocket (especially if I write data very frequently ~every 100 ms) but sometimes data is not sent at all. Not even after 5 sec. And sometimes several data chunks are internally buffered for a long period (several seconds) and then sent together.
m_socket = new QTcpSocket(this);
m_socket->connectToHost(QHostAddress::LocalHost, 45454);
sendDataEverySec()
{
QByteArray datagram(10000, 'a');
qint64 len = m_socket->write(datagram);
if(len != datagram.size())
qDebug() << "Error"; //this NEVER occurs in MY case.
m_socket->flush();
}
On receiver side, I use readyRead signal to know when data has arrived.
How can I ensure that data is sent immediately? Are there any better alternatives for what I am trying to do?
Edit:: When I am writing after long gaps of 1 second, I receive "QAbstractSocket::SocketTimeoutError" on receiver side everytime sender sends data. This error is not received if sender writes data frequently.
Is it OKAY to use QTcpSocket to stream data the way I am doing????
Edit 2: On receiver side, when readyRead signal is emitted, I was again checking while(m_socket->waitForReadyRead(500)) and I was getting "QAbstractSocket::SocketTimeoutError" due to this. Also, this check was preventing delivering of single chunks.
After going through docs more, it seems readyRead will be continuously emitted when new data is available, so no need for waitForReadyRead.
I am receiving all data sent but still data does not come immediately. Sometimes two-three chunks are merged. This may be because of delay on receiver side in reading data etc.
On receiver side, when readyRead signal is emitted, I was again checking while(m_socket->waitForReadyRead(500)) and I was getting "QAbstractSocket::SocketTimeoutError" due to this. Also, this check was preventing delivering of single chunks.
After going through docs more, it seems readyRead will be continuously emitted when new data is available, so there is no need for waitForReadyRead.
It had solved my issue.
my tipical solution for client server app.
on server side :
class Server: public QTcpServer {
public:
Server(QObject *parent = 0);
~Server();
private slots:
void readyRead();
void disconnected();
protected:
void incomingConnection(int);
};
on cpp:
void Server::incomingConnection(int socketfd) {
QTcpSocket *client = new QTcpSocket(this);
client->setSocketDescriptor(socketfd);
connect(client, SIGNAL(readyRead()), this, SLOT(readyRead()));
connect(client, SIGNAL(disconnected()), this, SLOT(disconnected()));
}
void Server::disconnected() {
QTcpSocket *client = (QTcpSocket*) sender();
qDebug() << " INFO : " << QDateTime::currentDateTime()
<< " : CLIENT DISCONNECTED " << client->peerAddress().toString();
}
void Server::readyRead() {
QTcpSocket *client = (QTcpSocket*) sender();
while (client->canReadLine()) {
//here i needed a string..
QString line = QString::fromUtf8(client->readLine()).trimmed();
}
}
on client:
class Client: public QTcpSocket {
public:
Client(const QHostAddress&, int, QObject* = 0);
~Client();
void Client::sendMessage(const QString& );
private slots:
void readyRead();
void connected();
public slots:
void doConnect();
};
on cpp:
void Client::readyRead() {
// if you need to read the answer of server..
while (this->canReadLine()) {
}
}
void Client::doConnect() {
this->connectToHost(ip_, port_);
qDebug() << " INFO : " << QDateTime::currentDateTime()
<< " : CONNESSIONE...";
}
void Client::connected() {
qDebug() << " INFO : " << QDateTime::currentDateTime() << " : CONNESSO a "
<< ip_ << " e PORTA " << port_;
//do stuff if you need
}
void Client::sendMessage(const QString& message) {
this->write(message.toUtf8());
this->write("\n"); //every message ends with a new line
}

Resources