Crash of the Server Application
-
Hi,
When I connect with the Server Application I receive the Crash Error on the line:
@if( !socket->setSocketDescriptor( m_descriptor ) )@
Please, run the project "ServerTimer" than run "ViewerServerTimer" and click the button "Connect"
ServerTime.pro
@
QT += core
QT += network
QT -= guiTARGET = ServerTimer
CONFIG += console
CONFIG -= app_bundleTEMPLATE = app
SOURCES += main.cpp
server.cpp
serverthread.cppHEADERS +=
server.h
serverthread.h
@main.cpp
@
#include <QCoreApplication>
#include "server.h"int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);Server server; if( !server.listen( QHostAddress::Any, 1234 ) ) { qCritical( "Cannot listen to port 1234." ); return 1; } return a.exec();
}
@server.h
@
#ifndef SERVER_H
#define SERVER_H#include <QTcpServer>
#include "serverthread.h"class Server : public QTcpServer
{
public:
Server();protected:
void incomingConnection(int descriptor);private:
ServerThread *thread;
};#endif // SERVER_H
@server.cpp
@
#include "server.h"Server::Server() : QTcpServer()
{
}void Server::incomingConnection( int descriptor )
{
thread = new ServerThread( descriptor, this );connect( thread, SIGNAL(finished()), thread, SLOT(deleteLater()) ); thread->start();
}
@serverthread.h
@
#ifndef SERVERTHREAD_H
#define SERVERTHREAD_H#include <QThread>
#include <QTimer>
#include <QTcpSocket>class ServerThread : public QThread
{
public:
ServerThread( int descriptor, QObject *parent );void run();
public slots:
void sendData();private:
int m_descriptor;private:
QTimer *timer;
QTcpSocket *socket;
};#endif // SERVERTHREAD_H
@serverthread.cpp
@
#include "serverthread.h"ServerThread::ServerThread( int descriptor, QObject *parent ) : QThread( parent )
{
m_descriptor = descriptor;
}void ServerThread::run()
{
if( !socket->setSocketDescriptor( m_descriptor ) )
{
qDebug( "Socket error!" );
return;
}timer = new QTimer(this); connect(timer, SIGNAL(timeout()), this, SLOT(sendData())); timer->start(1000);
}
void ServerThread::sendData() {
//socket->write( "data" );
}
@ViewerServerTimer.pro
@
SOURCES +=
main.cpp
timerdialog.cppHEADERS +=
timerdialog.hQT += network
@main.cpp
@
#include <QApplication>
#include "timerdialog.h"int main( int argc, char **argv )
{
QApplication app( argc, argv );TimerDialog win; //win.resize(500, 500); win.show(); return app.exec();
}
@timerdialog.h
@
#ifndef TIMERDIALOG_H
#define TIMERDIALOG_H#include <QDialog>
#include <QTcpSocket>
#include <QtGui>class TimerDialog : public QDialog
{
Q_OBJECT
public:
explicit TimerDialog(QWidget *parent = 0);signals:
public slots:
void on_btnConnect_clicked();
void readyRead();
void error(QAbstractSocket::SocketError error);private:
QTcpSocket *socket;
QLineEdit *leHostName;
QSpinBox *sbPort;
QPushButton *btnConnect;
QLineEdit *leTimer;
};#endif // TIMERDIALOG_H
@timerdialog.cpp
@
#include "timerdialog.h"TimerDialog::TimerDialog(QWidget *parent) :
QDialog(parent)
{
// Connecting
QLabel *lblHostName = new QLabel(tr("Host Name:"));
leHostName = new QLineEdit("localhost");QLabel *lblPort = new QLabel(tr("Port:")); sbPort = new QSpinBox; sbPort->setMaximum(9999); sbPort->setValue(1234); btnConnect = new QPushButton(tr("Connect")); QGridLayout *connectLayout = new QGridLayout; connectLayout->addWidget(lblHostName, 0, 0); connectLayout->addWidget(leHostName, 0, 1); connectLayout->addWidget(lblPort, 1, 0); connectLayout->addWidget(sbPort, 1, 1); connectLayout->addWidget(btnConnect, 2, 0, 1, 2); QGroupBox *connectGroupBox = new QGroupBox; connectGroupBox->setTitle(tr("Connecting")); connectGroupBox->setLayout(connectLayout); // Timer QLabel *lblTimer = new QLabel(tr("Timer:")); leTimer = new QLineEdit(""); leTimer->setReadOnly(true); QHBoxLayout *timerLayout = new QHBoxLayout; timerLayout->addWidget(lblTimer); timerLayout->addWidget(leTimer); QGroupBox *timerGroupBox = new QGroupBox; timerGroupBox->setTitle(tr("Output From Server")); timerGroupBox->setLayout(timerLayout); // MainLaoyt QVBoxLayout *mainLayout = new QVBoxLayout; mainLayout->addWidget(connectGroupBox); mainLayout->addWidget(timerGroupBox); this->setLayout(mainLayout); socket = new QTcpSocket; connect(btnConnect, SIGNAL(clicked()), this, SLOT(on_btnConnect_clicked())); connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(error(QAbstractSocket::SocketError))); connect(socket, SIGNAL(readyRead()), this, SLOT(readyRead()));
}
void TimerDialog::on_btnConnect_clicked() {
socket->connectToHost(leHostName->text(), sbPort->value());btnConnect->setEnabled(false);
}
void TimerDialog::readyRead() {
QString time;
time = socket->read(256);
leTimer->setText(time);
}void TimerDialog::error(QAbstractSocket::SocketError error) {
if( error == QAbstractSocket::RemoteHostClosedError )
return;QMessageBox::warning(this, tr("Error"), tr("TCP error: %1").arg( socket->errorString())); btnConnect->setEnabled(true);
}
@Thank you!
-
Hi,
Did you run your program through a debugger ?
Did you check that you initialize all your variables ?
-
Thank you for reply :)
Yes, I did it.
The program crashed on the line:
@if( !socket->setSocketDescriptor( m_descriptor ) )@
the variable m_descriptor is initialized in constructor. It's very simple application but I don't know where my mistake. Please, help me. It is very important for me :(
-
And what about socket ?
-
Thank you. I wrote:
@
void ServerThread::run()
{
socket = new QTcpSocket;
...
}
@But now output is:
@QObject: Cannot create children for a parent that is in a different thread.
(Parent is QThread(0x547258), parent's thread is QThread(0x5416a8), current thre
ad is QThread(0x547258)
Object::connect: No such slot QThread::sendData() in ../ServerTimer/serverthread
.cpp:20@ -
"You're doing it wrong":http://blog.qt.digia.com/blog/2010/06/17/youre-doing-it-wrong/ . That's what happens if people subclass QThread without knowing about the implications this has.
The socket variable is a member of your QThread subclass. The instance of your QThread subclass lives in the context of the main thread, so the instance of the member variable socket also lives in the main thread. But everything that happens inside the run method of your QThread subclass happens in the context of the new thread. So when you try to asign to the socket member var from inside the run() function you get the "QObject: Cannot create children for a parent that is in a different thread." output.
Consider using "the worker object approach":http://qt-project.org/wiki/QThreads_general_usage .
-
Thank you. I'll read about threads.
Why when I comment the timer does the program works?
@
#include "serverthread.h"ServerThread::ServerThread( int descriptor, QObject *parent ) : QThread( parent )
{
m_descriptor = descriptor;
}void ServerThread::run()
{
socket = new QTcpSocket;if( !socket->setSocketDescriptor( m_descriptor ) ) { emit error(socket->error()); return; }
// timer = new QTimer(this);
// connect(timer, SIGNAL(timeout()), this, SLOT(sendData()));
// timer->start(1000);qDebug() << m_descriptor << " Client Connected"; exec();
}
void ServerThread::sendData() {
//socket->write( "time" );
}
@I want to use a timer in my thread.
-
What do you mean by "works" ?
-
[quote author="SGaist" date="1378153105"]What do you mean by "works" ?[/quote]
I don't see the message:
@
Listening...
QObject: Cannot create children for a parent that is in a different thread.
(Parent is ServerThread(0x3d7258), parent's thread is QThread(0x3d16a8), current
thread is ServerThread(0x3d7258)
272 Client Connected
@Maybe is this right:
@timer = new QTimer(0);@
-
No... When I ran my application I received from server the word "time" and the report:
Listening...
268 Client Connected
QObject: Cannot create children for a parent that is in a different thread.
(Parent is QNativeSocketEngine(0x1e1e430), parent's thread is ServerThread(0x627
258), current thread is QThread(0x6216a8)
QSocketNotifier: socket notifiers cannot be disabled from another thread
ASSERT failure in QCoreApplication::sendEvent: "Cannot send events to objects ow
ned by a different thread. Current thread 6216a8. Receiver '' (of type 'QNativeS
ocketEngine') was created in thread 627258", file kernel/qcoreapplication.cpp, l
ine 535This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
Press <RETURN> to close this window...@#include "serverthread.h"
ServerThread::ServerThread( int descriptor, QObject *parent ) : QThread( parent )
{
m_descriptor = descriptor;
}void ServerThread::run()
{
socket = new QTcpSocket;if( !socket->setSocketDescriptor( m_descriptor ) ) { emit error(socket->error()); return; } timer = new QTimer(0); connect(timer, SIGNAL(timeout()), this, SLOT(sendData())); timer->start(1000); qDebug() << m_descriptor << " Client Connected"; exec();
}
void ServerThread::sendData() {
socket->write( "time" );
}
@ -
Before going further and since you seem to be starting with network + threads... Are you sure you need threads ? (QTcpServer/Socket are asynchronous so you don't really need them). Did you take a look at the QtNetwork module examples ? (Thinking of the client/fortune example and the threaded version)
-
Thank you. I will have a many clients for my server. I'll see network examples from Qt SDK.
-
Take a look to this tutorial:
"Advanced Asynchronous QTcpServer with QThreadPool":http://voidrealms.com/viewtutorial.aspx?id=39 -
[quote author="qxoz" date="1378183845"]Take a look to this tutorial:
"Advanced Asynchronous QTcpServer with QThreadPool":http://voidrealms.com/viewtutorial.aspx?id=39
[/quote]Thank you very much :)