PDA

View Full Version : My QTCPServer crashes



Mr_Burns
23rd May 2011, 17:09
Hi everybody,

I'm new to Qt and this forum. After my first steps in the last few weeks with Qt, I tried to write a server which can handle multiple clients. The basis for my program is "Multi client server without threading (http://www.qtcentre.org/wiki/index.php?title=Multi_client_server_without_thread ing)" of this site.

My methode Server::start() ist connected with a button, also the methode Server::stop(). When I start my server all works fine, but when I try to stop my server and restart it again with the buttons, my Server crashes as soon as I want to connect with the client. Has anybody of you an idea for a solution for my problem?

Here my code:



// network.h
#ifndef NETWORK_H
#define NETWORK_H

#include <QTcpServer>
#include <QTcpSocket>
#include <QHostAddress>
#include <QList>
#include <QHash>
#include <QBuffer>
#include "mainwindow.h"

class Server : public QTcpServer {
Q_OBJECT

protected:
void sendHello(QTcpSocket *client);

protected slots:
void handleNewConnection();
void clientDisconnected();
void start(int port = 10002);
void stop();
void read();

private:
QList<QTcpSocket *> clientConnections;
QHash<QTcpSocket*, QBuffer*> buffers;

public:
explicit Server();
~Server();
};


#endif // NETWORK_H




// network.c
#include "network.h"

Server::Server() {
}

Server::~Server() {
stop();
}

void Server::stop() {
close();
qDeleteAll(clientConnections);
}

void Server::start(int port) {
if(!listen(QHostAddress::Any, port)) {
return;
}
connect(this, SIGNAL(newConnection()), this, SLOT(handleNewConnection()));
}

void Server::handleNewConnection() {
while (hasPendingConnections()) {
QTcpSocket *client = nextPendingConnection();
QBuffer* buffer = new QBuffer(this);
buffer->open(QIODevice::ReadWrite);
buffers.insert(client, buffer);
connect(client, SIGNAL(disconnected()), this, SLOT(clientDisconnected()));
connect(client, SIGNAL(readyRead()), this, SLOT(read()));
clientConnections.append(client);

sendHello(client);
}
}

void Server::clientDisconnected() {
QTcpSocket *client = qobject_cast<QTcpSocket *>(sender());

if(!client) return;

clientConnections.removeAll(client);
client->deleteLater();
}

void Server::sendHello(QTcpSocket *client) {
if(!client) return;
client->write("Hello\n");
}

void Server::read() {
QTcpSocket *client = qobject_cast<QTcpSocket *>(sender());
QBuffer* buffer = buffers.value(client);

if(!client) return;

qint64 bytes = buffer->write(client->readAll());
buffer->seek(buffer->pos() - bytes);
while (buffer->canReadLine()) {

QByteArray line = buffer->readLine();

switch(line[0]) {
case 'a' : client->write(line);
break;
}
}
}


Thank you in advance.

Santosh Reddy
23rd May 2011, 18:20
Did you try debugging? where does it crash? have a look at the stack when it crashes, it should give you very good idea what went worng.

Mr_Burns
23rd May 2011, 19:04
Hi Santosh Reddy,

thanks for your fast answer ;-). No, I haven't debugged my code, yet, but I did it after your post. I've only checked the issues from my compiler, before. But now, with debugging, it shows like qDeleteAll is the problem. Exactly, on this PC my program is crashing when I close my server in second time. I did the following steps:

1. run Server::start()
2. connected with an terminal
3. run Server::stop()
4. run Server::start()
5. connected again with an terminal
6. run Server::stop() --> my program crashed

Comment: at another computer some hours ago, my program crashed at point 5, as I wrote in my first post.

Do you have an idea what I did wrong? How I can look at my stack?

Best regards
Mr_Burns

Santosh Reddy
23rd May 2011, 19:24
If you use QtCreator, then this is the screenshot, else refer the IDE docs.
6467

Added after 6 minutes:

You should be using either
qDeleteAll() or
deleteLater() not both.

You may want to replace


qDeleteAll(XXXX); //with XXXX.clear();

Mr_Burns
23rd May 2011, 19:50
You may want to replace


qDeleteAll(XXXX); //with XXXX.clear();


When I do it, my program doesn't crash now ;-). My server did not accept new connetions but my active connections to my clients were not killed. But why? - Normally I think xxx.clear() removed all items from my list and with them my connections must be closed or did I understand anything wrong?

Santosh Reddy
23rd May 2011, 20:01
xxx.clear() will only remove the Objects from the list (in this case they happen to be pointers to the clients), they aer just removed from the list not really deleted / closed.

If I understand you code correctly you wanted to delete the clients in


void Server::clientDisconnected() {
QTcpSocket *client = qobject_cast<QTcpSocket *>(sender());

if(!client) return;

clientConnections.removeAll(client);
client->deleteLater();
}

...
connect(client, SIGNAL(disconnected()), this, SLOT(clientDisconnected())); //This is supposed to make the connection
...


try adding following to your code (or somthing like this, which will trigger the above connection)



void Server::stop() {
QTcpSocket *client;
while(clientConnections.count() > 0)
{
client = clientConnections.takeFirst(); // this will both remove and return the object, so xxxx.clear() is not needed
client.disconnectFromHost ();
}
close();
}

Mr_Burns
23rd May 2011, 20:17
Hi Santosh Reddy,

okay, now I understand what xxx.clear() and your code do. Finally my little program works fine and learned a lot ;-).
Thank you for your help !!!!

Best regards,
Mr_Burns