Hi. I would like to ask about your opinion on some kind of problem. I have QTcpServer (working with QSslSockets). There is no threads (except main theadpool). Lets say that the client is trying to connect. Server will take connection and accept it. He will store some client data in containers and perform the necessary connections.
server.h
class server {
//not significant
protected:
void incomingConnection(int handle);
private slots:
void isDisconnected(client *c = 0);
void isReadyRead();
//not significant
};
class server {
//not significant
protected:
void incomingConnection(int handle);
private slots:
void isDisconnected(client *c = 0);
void isReadyRead();
//not significant
};
To copy to clipboard, switch view to plain text mode
server.cpp
void server::incomingConnection(int handle) {
//blabla
client *c = new client(this);
if(c->setSocketDescriptor(handle)) {
connect(c, SIGNAL(readyRead()), this, SLOT(isReadyRead()));
connect(c, SIGNAL(disconnected()), this, SLOT(isDisconnected()));
connect(c, SIGNAL(encrypted()), this, SLOT(isEncrypted()));
connect(c, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(sslErrors(QList<QSslError>)));
c->setPrivateKey(privateKey);
c->setLocalCertificate(certificate);
c->startServerEncryption();
} else {
c->deleteLater();
}
}
void server::isDisconnected(client *c) {
if(c == 0)
c = static_cast<client*>(sender());
//cleaning operations (cleaning containters)
//and now:
c->deleteLayer();
}
void server::incomingConnection(int handle) {
//blabla
client *c = new client(this);
if(c->setSocketDescriptor(handle)) {
connect(c, SIGNAL(readyRead()), this, SLOT(isReadyRead()));
connect(c, SIGNAL(disconnected()), this, SLOT(isDisconnected()));
connect(c, SIGNAL(encrypted()), this, SLOT(isEncrypted()));
connect(c, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(sslErrors(QList<QSslError>)));
c->setPrivateKey(privateKey);
c->setLocalCertificate(certificate);
c->startServerEncryption();
} else {
c->deleteLater();
}
}
void server::isDisconnected(client *c) {
if(c == 0)
c = static_cast<client*>(sender());
//cleaning operations (cleaning containters)
//and now:
c->deleteLayer();
}
To copy to clipboard, switch view to plain text mode
Ok now server is waiting for some data.
server.cpp
void server::isReadyRead() {
client *c = static_cast<client*>(sender());
buffer = c->readAll();
//parsing user data:
if(isLoggedAlready(buffer)) { //maybe client is going to trick me by making multiple connection
client *old = findOldConnection(buffer);
isDisconnected(old); //lets remove his old connection
} else {
//do something else
}
}
void server::isReadyRead() {
client *c = static_cast<client*>(sender());
buffer = c->readAll();
//parsing user data:
if(isLoggedAlready(buffer)) { //maybe client is going to trick me by making multiple connection
client *old = findOldConnection(buffer);
isDisconnected(old); //lets remove his old connection
} else {
//do something else
}
}
To copy to clipboard, switch view to plain text mode
Is it safe to call this slot (isDisconnected) in such a way ? What if:
a) client will disconnect suddenly (faulty internet connection or ethernet cable has been removed, etc).
b) server still does not know (for a while) that something is wrong with the client.
c) client performs new connection as soon as possible and send some data to him.
d) server will check data (using isLoggedAlready function) and finds that the client is already logged in, so he must remove old connection.
What if somewhere in the events loop, between these steps server has placed information about broken connection ? Is it possible to call isDisconnected slot twice ? it could be dangerous especially when we are releasing memory there.
Bookmarks