PDA

View Full Version : QTcpServer--cleaning up when clients disconnect



davethomaspilot
20th February 2015, 21:32
I want to use QTcpServer (I think) to create QTcpsocket each time a client connects.

I want the connection to stay open until the client side disconnects. Then I want the socket to be closed and associated memory freed.

So, I was thinking something like this for the newConnection slot of QTcpServer:



oid EjsServer::newConnection()
{

QTcpSocket *socket = server->nextPendingConnection();
connect(socket,SIGNAL(disconnected()),socket,SLOT( deleteLater()));
clientList.append(socket);
socket->write("Connected to APES EJS Server\r\n");
socket->flush();

socket->waitForBytesWritten(3000);

//socket->close();
}

But, I think once newConnection finishes, "socket" will go out of scope. But will the memory it's pointing still be good so it's ok to have it as an argument to the deleteLater() slot?

I also need to remove the socket from "clientList, so instead of just connecting to the socket's "deleteLater", I'm thinking I need a slot in EjsServer that removes the socket from the list then calls deleteLater. But, how to get a handle to the right socket? None of the QTcpSocket signals include a pointer to the QTcpSocket the emitted the signal.

I guess I need a good QTcpServer example. The fortune example isn't helpful, since it just writes to a client on connection, then closes the connection. Or, implement without using QTcpserver.

Thanks

Added after 21 minutes:

I could use QObject::sender() in the slot to remove the right QTcpSocket * from the list and invoke deleteLater(), but it "feels like" i'm not using the class as intended.

wysota
20th February 2015, 21:46
But, I think once newConnection finishes, "socket" will go out of scope.
Yes. the pointer will go out of scope. The object behind it will not.


But will the memory it's pointing still be good so it's ok to have it as an argument to the deleteLater() slot?
Yes, your approach is correct.


I also need to remove the socket from "clientList, so instead of just connecting to the socket's "deleteLater", I'm thinking I need a slot in EjsServer that removes the socket from the list then calls deleteLater. But, how to get a handle to the right socket? None of the QTcpSocket signals include a pointer to the QTcpSocket the emitted the signal.
There is QObject::sender() and there is also QObject::destroyed(QObject*) which you can use.

davethomaspilot
20th February 2015, 22:07
Thanks,

For reference, here's what I did:



void EjsServer::newConnection()
{
// need to grab the socket
QTcpSocket *socket = server->nextPendingConnection();
connect(socket,SIGNAL(disconnected()),this,SLOT(cl ientDisconnected()));
clientList.append(socket);
socket->write("Connected to APES EJS Server\r\n");
socket->flush();

socket->waitForBytesWritten(3000);

//socket->close();
}

void EjsServer::clientDisconnected()
{
QTcpSocket *clientSocket = qobject_cast<QTcpSocket *>(QObject::sender());

int idx = clientList.indexOf(clientSocket);
if (idx!=-1)
clientList.removeAt(idx);

clientSocket->deleteLater();
}


That should be leak free?

anda_skoa
2nd March 2015, 12:29
Yes, that looks ok.

Cheers,
_