I have problem with sender() in QTcpSocket::disconnected signal
-
Hello. I make server and client apps in C++ Qt.
In server side I store sockets of connected clients in QVector<QTcpSocket*>.
I want to remove socket from QVector when I close a client's window. But in function for signal QTcpSocket::disconnected the sender() returns nullptr and I can't get any information of this lost socket.
Help pls :C
Sorry for mistakes. -
@Kirill-Gusarev
If that is so you will need to use lambdas, to which you can pass a parameter of which socket is closing, instead ofsender()
, which you should avoid if possible. -
Hi and welcome to devnet,
Can you share the code where you handle the new sockets and their disconnection handling ?
-
@Kirill-Gusarev
Actually I don't know why you need to know about the sender here anyway, and hence might have wanted a lambda? Don't you just want to removethis
from yourQVector<QTcpSocket*>
indisconnected
slot? @SGaist askedCan you share the code where you handle the new sockets and their disconnection handling ?
-
@SGaist Hi!
Incoming connection:
void Server::incomingConnection(qintptr socketDescriptor) { socket = new QTcpSocket(); socket->setSocketDescriptor(socketDescriptor); connect(socket, &QTcpSocket::readyRead, this, &Server::slotReadyRead); // connect(socket, &QTcpSocket::disconnected, socket, &QTcpSocket::deleteLater); /* connect(socket, &QTcpSocket::disconnected, socket, [=]() { qDebug() << "Number of sockets:" << sockets.size(); qDebug() << "SOCKET DISCONNECTED"; // qDebug() << "Sockets removed:" << erase(sockets, sender()); qDebug() << "Sockets removed:" << sockets.removeOne(sender()); qDebug() << "Number of sockets:" << sockets.size(); // qDebug() << sender()->objectName(); // Краш // qDebug() << ((QTcpSocket*)(sender()))->socketDescriptor(); // Краш qDebug() << qobject_cast<QTcpSocket*>(sender())->socketDescriptor(); }); */ connect(socket, &QTcpSocket::disconnected, socket, [=]() { QTcpSocket* client = qobject_cast<QTcpSocket*>(sender()); if (client) { qDebug() << "if"; qDebug() << client; } else { qDebug() << "else"; qDebug() << client->socketDescriptor(); // crash (Segmentation fault) } }); sockets.push_back(socket); qDebug() << "client connected:" << socketDescriptor; }
Function for "disconnected" signal:
connect(socket, &QTcpSocket::disconnected, socket, [=]() { QTcpSocket* client = qobject_cast<QTcpSocket*>(sender()); if (client) { qDebug() << "if"; qDebug() << client; } else { qDebug() << "else"; qDebug() << client->socketDescriptor(); // crash (Segmentation fault) } });
-
@Kirill-Gusarev
So you already have a lambda anyway.
Why are you looking atsender()
and not just usingthis
?
Oh, I get it, this is server, you expectsender()
to be client?
And even when it works, why would you want to access a socket'ssocketDescriptor()
during disconnect? I don't know whether it's valid at that point.sockets.push_back(socket);
So don't you just want to remove
socket
orthis
fromsockets
duringdisconnected
? I'm not understanding why you needsender()
(norsocketDescriptor()
). -
@JonB sorry i have a 10 minute messaging limit because i am a new user.
Yes, it is a Server-side code in Server:QTcpServer class.
Calling of ->socketDescriptor is a just example of crashing while trying to get any information from sender().
I just want to delete this socket from QVector. I thought i can take socket information from sender() :((, but I take only empty pointer(((
-
@Kirill-Gusarev
I have now answered a couple of times:So don't you just want to remove
socket
orthis
from sockets duringdisconnected
? I'm not understanding why you needsender()
-
@JonB said in I have problem with sender() in QTcpSocket::disconnected signal:
@Kirill-Gusarev
If that is so you will need to use lambdas, to which you can pass a parameter of which socket is closing, instead ofsender()
, which you should avoid if possible.[socket](){}
[socket] - is it "pass a parameter of which socket is closing"?
-
@Kirill-Gusarev
Indeed! Specifically it is whatever valuesocket
had at the time thatconnect()
statement was executed. Which was immediately prior tosockets.push_back(socket);
.Or it would have been
this
if you had derived fromQTcpSocket
and just provided a slot to attach todisconnected
. But with lambda you can pass it whatever variables you like without having to subclass. -
@JonB thank you. Sorry for my mistakes and missunderstandings, my main language is russian.
[socket] - that helped. I solved the problem :]I have updated code (added QTcpSocket *currentSocket):
void Server::incomingConnection(qintptr socketDescriptor) { socket = new QTcpSocket(); socket->setSocketDescriptor(socketDescriptor); connect(socket, &QTcpSocket::readyRead, this, &Server::slotReadyRead); QTcpSocket *currentSocket = socket; connect(socket, &QTcpSocket::disconnected, socket, [=]() { qDebug() << currentSocket << "socket removed:" << sockets.removeOne(currentSocket); }); sockets.push_back(socket); qDebug() << "client connected" << socketDescriptor; }