La conexión (en un proyecto QT) no funciona
Frecuentes
Visto 1,954 equipos
1
Estoy empezando a crear mi primera aplicación multiproceso, utilizando las bibliotecas QT.
Siguiendo la guía qt sobre QTcpServer y QTcpSocket, escribí una aplicación de servidor que crea la conexión con este constructor:
Connection::Connection(QObject *parent) : QTcpServer(parent)
{
server = new QTcpServer();
QString ipAddress;
if (ipAddress.isEmpty())
ipAddress = QHostAddress(QHostAddress::LocalHost).toString();
if (!server->listen(QHostAddress(ipAddress),41500))
{
qDebug() << "Enable to start server";
server->close();
return;
}
connect(server,SIGNAL(newConnection()),this,SLOT(incomingConnection()));
}
Esta es la función incomingConnection() que crea un nuevo hilo cada vez que un nuevo cliente intenta conectarse:
void Connection::incomingConnection()
{
QTcpSocket *socket = new QTcpSocket();
socket = this->nextPendingConnection();
MyThreadClass *thread = new MyThreadClass(socket, server);
qDebug() << "connection required by client";
if (thread != 0)
{
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
thread->start();
}
else
qDebug() << "Error: Could not create server thread.";
}
Ahora, esto es MyThreadClass:
MyThreadClass::MyThreadClass(QTcpSocket *socket, QTcpServer *parent) : QThread(parent)
{
tcpSocket = new QTcpSocket();
database = new Db();
blockSize = 0;
tcpSocket = socket;
qDebug() << "creating new thread";
}
MyThreadClass::~MyThreadClass()
{
database->~Db();
}
void MyThreadClass::run()
{
qDebug() << "Thread created";
connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(dataAvailable()));
exec();
}
void MyThreadClass::dataAvailable()
{
qDebug() << "data available";
QDataStream in(tcpSocket);
in.setVersion(QDataStream::Qt_4_0);
if (blockSize == 0) {
if (tcpSocket->bytesAvailable() < (int)sizeof(qint16))
return;
in >> blockSize;
}
if (tcpSocket->bytesAvailable() < blockSize)
return;
QString string;
in >> string;
//[...]
}
El código se compila bien, pero cuando inicio un cliente (después de iniciar el servidor), recibo el siguiente error del servidor:
QObject::connect: Cannot connect (null)::readyRead() to QThread::dataAvailable()
Entonces el servidor no puede recibir datos por parte del cliente.
¿Alguien tiene alguna idea?
gracias de antemano daniel
1 Respuestas
2
socket = this->nextPendingConnection();
debiera ser:
socket = server->nextPendingConnection();
porque estás usando el server
miembro y no this
como el activo QTcpServer
, la clase Connection
ni siquiera debería heredar de QTcpServer
, pero solo de QObject
.
Además, estás haciendo un mal uso QThread
. Deberías leer Señales y ranuras a través de hilos, y probablemente Hilos y el módulo SQL, Si Db
está utilizando el módulo QtSql.
contestado el 23 de mayo de 12 a las 03:05
Ese error proviene de un conocimiento deficiente de C++. Por eso no lo mencioné al principio. - kamil klimek
#Kamil Klimek: Lo sé porque aprendí C++ solo. Probablemente si supiera muy bien como usted C ++, entonces no necesitaría preguntar nada aquí. Además, si no quieres, nadie te obliga a responder - Daniele
#alexisdm: Muchas gracias. Sabía que había muchos errores, pero, siguiendo tus consejos, ahora el proyecto avanza bastante bien. En realidad, el servidor y el cliente se comunican como quiero. - Daniele
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas c++ qt qthread qtcpsocket qtcpserver or haz tu propia pregunta.
no estoy seguro pero creo
socket
pertenece al primer hilo, y lo estás pasando a través de un hilo recién creado, y dentro, estás haciendotcpSocket = new QTcpSocket();
que parece no poder reasignar datos fuera del hilo actual. - sorush-r¿Dónde aprendiste C++? ¿Sabes algo sobre montón y pila? Estás perdiendo memoria. También está llamando a destructor manualmente en lugar de usar eliminar. Otra cosa es que incluso si la conexión a readyRead funcionara bien, su ranura se llamaría en un hilo diferente al que espera. Hay muchas cosas que corregir en su código. ¿También podría proporcionar la declaración MyThreadClass? En su lugar, comenzaría aprendiendo algunos conceptos básicos de C ++ (como la administración de memoria). Estás haciendo tantas cosas mal, que ni siquiera me molestaría con tu problema de conexión hasta que obtengas algunos conceptos básicos de C ++: Kamil Klimek
tcpSocket = new QTcpSocket();
y luegotcpSocket = socket;
. ¿¿¿Por qué??? ¿¿Por qué harías eso?? - Diego Schulzestás bien. Ese código es el resultado de muchos cambios, por lo que hay muchos errores... lo siento mucho... Sin embargo, si cancela "tcpSocket = new QTcpSocket();" instrucción, el problema no cambia... - Daniele
¿Por qué creas un
QTcpServer
cuando lo heredas? ¡¡es incómodo!! no menciono otros problemas porque alguien ya te lo ha dicho... "muchos cambios" no es excusa para dejar ese tipo de basura en el código! - andrea.marangoni