okay instead of while I use now exec(). Am I doing it right with the exit()?
The connect works fine and also the reading of the incoming data.
But writing to the socket by emitting a signal does not work - Cannot create children for a parent that is in a different thread - is the error. I tried moving several objects to several threads by using moveToThread(currentThread()). What should I move to which place?
multiserver.cpp
MultiServer
::MultiServer(QObject *parent
){
}
void MultiServer::incomingConnection(int socketDescriptor)
{
ConnectionThread *thread = new ConnectionThread(socketDescriptor, this);
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
thread->start();
}
MultiServer::MultiServer(QObject *parent)
: QTcpServer(parent)
{
}
void MultiServer::incomingConnection(int socketDescriptor)
{
ConnectionThread *thread = new ConnectionThread(socketDescriptor, this);
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
thread->start();
}
To copy to clipboard, switch view to plain text mode
ConnectionThread.h
#ifndef CONNECTIONTHREAD_H
#define CONNECTIONTHREAD_H
#include <QThread>
#include <QTcpSocket>
#include <QMutex>
#include <QWaitCondition>
#include "tcpsocket.h"
class ConnectionThread
: public QThread {
Q_OBJECT
public:
ConnectionThread
(int socketDescriptor,
QObject *parent
);
~ConnectionThread();
void run();
void stop();
signals:
private slots:
void readData();
private:
int socketDescriptor;
};
#endif
#ifndef CONNECTIONTHREAD_H
#define CONNECTIONTHREAD_H
#include <QThread>
#include <QTcpSocket>
#include <QMutex>
#include <QWaitCondition>
#include "tcpsocket.h"
class ConnectionThread : public QThread
{
Q_OBJECT
public:
ConnectionThread(int socketDescriptor, QObject *parent);
~ConnectionThread();
void run();
void stop();
signals:
void error(QTcpSocket::SocketError socketError, const QString &message);
void dataAvailable(QString &msg);
private slots:
void readData();
void writeData(QString &msg);
private:
int socketDescriptor;
QString text;
QMutex mutex;
QWaitCondition cond;
QBuffer* buffer;
QTcpSocket* m_tcpSocket;
};
#endif
To copy to clipboard, switch view to plain text mode
ConnectionThread.cpp
#include "ConnectionThread.h"
#include <QtNetwork>
ConnectionThread
::ConnectionThread(int socketDescriptor,
QObject *parent
), socketDescriptor(socketDescriptor)
{
qDebug() << currentThreadId ();//Thread Y
}
ConnectionThread::~ConnectionThread ()
{
stop();
}
void ConnectionThread::stop()
{
exit();
}
void ConnectionThread::run()
{
qDebug() << currentThreadId();//Thread X - Different thread ID than all others
if (!m_tcpSocket->setSocketDescriptor(socketDescriptor)) {
emit error(m_tcpSocket->error(), m_tcpSocket->errorString());
return;
}
connect(m_tcpSocket, SIGNAL(readyRead()), SLOT(readData()));
connect(this,
SIGNAL(dataAvailable
(QString &)),
SLOT(writeData
(QString &)));
exec();
}
void ConnectionThread::readData()
{
qDebug() << "data arrived";
qDebug() << currentThreadId (); // Thread Y
qint64 bytes = buffer->write(m_tcpSocket->readAll());
buffer->seek(buffer->pos() - bytes);
while (buffer->canReadLine())
{
//log_stat->append("received: "+line.simplified());
qDebug() << line;
}
emit dataAvailable(msg);//here is the Error -Cannot create children for a parent that is in a different thread - emitted
}
void ConnectionThread
::writeData(QString &msg
) {
qDebug() << msg;
qDebug() << currentThreadId (); //Thread Y
qint64 blockSize = msg.size();
m_tcpSocket->write(msg.toAscii().data(),blockSize);
}
#include "ConnectionThread.h"
#include <QtNetwork>
ConnectionThread::ConnectionThread(int socketDescriptor, QObject *parent)
: QThread(parent)
, socketDescriptor(socketDescriptor)
{
qDebug() << currentThreadId ();//Thread Y
}
ConnectionThread::~ConnectionThread ()
{
stop();
}
void ConnectionThread::stop()
{
exit();
}
void ConnectionThread::run()
{
qDebug() << currentThreadId();//Thread X - Different thread ID than all others
m_tcpSocket = new QTcpSocket();
buffer = new QBuffer();
buffer->open(QIODevice::ReadWrite);
if (!m_tcpSocket->setSocketDescriptor(socketDescriptor)) {
emit error(m_tcpSocket->error(), m_tcpSocket->errorString());
return;
}
connect(m_tcpSocket, SIGNAL(readyRead()), SLOT(readData()));
connect(this, SIGNAL(dataAvailable(QString &)), SLOT(writeData(QString &)));
exec();
}
void ConnectionThread::readData()
{
qDebug() << "data arrived";
qDebug() << currentThreadId (); // Thread Y
qint64 bytes = buffer->write(m_tcpSocket->readAll());
buffer->seek(buffer->pos() - bytes);
while (buffer->canReadLine())
{
QString line = buffer->readLine();
//log_stat->append("received: "+line.simplified());
qDebug() << line;
}
QString msg = "reply code";
emit dataAvailable(msg);//here is the Error -Cannot create children for a parent that is in a different thread - emitted
}
void ConnectionThread::writeData(QString &msg)
{
qDebug() << msg;
qDebug() << currentThreadId (); //Thread Y
qint64 blockSize = msg.size();
m_tcpSocket->write(msg.toAscii().data(),blockSize);
}
To copy to clipboard, switch view to plain text mode
AND just for Information:
Working version without signal and slots - but with a strict order of reading and writing
ConnectionThread.cpp version 2
#include "ConnectionThread.h"
#include <QtNetwork>
ConnectionThread
::ConnectionThread(int socketDescriptor,
QObject *parent
), socketDescriptor(socketDescriptor)
{
}
void ConnectionThread::run()
{
while(1)// ToDo no quit
{
// int st;
// switch(tcpSocket.state())
// {
// case QTcpSocket::UnconnectedState:
// st= 0;
// break;
// case QTcpSocket::HostLookupState:
// st= 1;
// break;
// case QTcpSocket::ConnectingState:
// st= 2;
// break;
// case QTcpSocket::ConnectedState:
// st= 3;
// break;
// case QTcpSocket::BoundState:
// st= 4;
// break;
// case QTcpSocket::ListeningState:
// st= 5;
// break;
// case QTcpSocket::ClosingState:
// st= 6;
// break;
// }
// qDebug() << st;
while (tcpSocket.bytesAvailable() < (int)sizeof(quint16)) {
if (!tcpSocket.waitForReadyRead(Timeout)) {
qDebug() << "Nothing arrived!";
{
qDebug() << "Connection broken!";
emit error(tcpSocket.error(), tcpSocket.errorString());
return;
}
continue;
}
}
char *buffer = (char*) malloc (1024);
quint64 n = tcpSocket.read(buffer,1024);
mutex.lock();
qDebug() << txt;
//cond.wait(&mutex); //wait condition to wake up thread -> obsolete waiting above for data arriving - maybe connect with incoming data
mutex.unlock();
QString msg
= "Hello, world - here is rtproc! Give me some data to process! \n";
//Todo just for debug purpose qint64 blockSize = msg.size();//Todo just for debug purpose
tcpSocket.write(msg.toAscii().data(),blockSize);//Todo just for debug purpose
tcpSocket.flush();//Todo just for debug purpose
}
// tcpSocket.disconnectFromHost();
// tcpSocket.waitForDisconnected();
}
#include "ConnectionThread.h"
#include <QtNetwork>
ConnectionThread::ConnectionThread(int socketDescriptor, QObject *parent)
: QThread(parent)
, socketDescriptor(socketDescriptor)
{
}
void ConnectionThread::run()
{
while(1)// ToDo no quit
{
// int st;
// switch(tcpSocket.state())
// {
// case QTcpSocket::UnconnectedState:
// st= 0;
// break;
// case QTcpSocket::HostLookupState:
// st= 1;
// break;
// case QTcpSocket::ConnectingState:
// st= 2;
// break;
// case QTcpSocket::ConnectedState:
// st= 3;
// break;
// case QTcpSocket::BoundState:
// st= 4;
// break;
// case QTcpSocket::ListeningState:
// st= 5;
// break;
// case QTcpSocket::ClosingState:
// st= 6;
// break;
// }
// qDebug() << st;
while (tcpSocket.bytesAvailable() < (int)sizeof(quint16)) {
if (!tcpSocket.waitForReadyRead(Timeout)) {
qDebug() << "Nothing arrived!";
if(tcpSocket.state()!=QTcpSocket::ConnectedState)
{
qDebug() << "Connection broken!";
emit error(tcpSocket.error(), tcpSocket.errorString());
return;
}
continue;
}
}
char *buffer = (char*) malloc (1024);
quint64 n = tcpSocket.read(buffer,1024);
mutex.lock();
QString txt = QString(buffer).mid(0,n);
qDebug() << txt;
//cond.wait(&mutex); //wait condition to wake up thread -> obsolete waiting above for data arriving - maybe connect with incoming data
mutex.unlock();
QString msg = "Hello, world - here is rtproc! Give me some data to process! \n";//Todo just for debug purpose
qint64 blockSize = msg.size();//Todo just for debug purpose
tcpSocket.write(msg.toAscii().data(),blockSize);//Todo just for debug purpose
tcpSocket.flush();//Todo just for debug purpose
}
// tcpSocket.disconnectFromHost();
// tcpSocket.waitForDisconnected();
}
To copy to clipboard, switch view to plain text mode
Bookmarks