我尝试使用QTcpSserver
,这将一次与一个且仅一个客户端保持连接,直到客户端断开连接。所以,我在客户端使用成员指针保存在我的班级中。
问题出现在:我在互联网上看到的示例disconnected()
后,它被称为deleteLater()
。很好,但我会再次使用此类成员指针进行另一个连接。请记住,服务器一次只保留一个客户端。那么,如果套接字对象在其上分配了另一个连接后被删除怎么办?
我的意思是:
class TcpServer(QObject* o) : public QTcpServer {
...
private:
QTcpSocket* client;
}
void TcpServer::connected() {
client = this->nextPendingConnection();
this->pauseAccepting();
connect(client, SIGNAL(disconnected()), client, SLOT(clientDisconnected()));
}
void TcpServer::clientDisconnected() {
client->deleteLater();
this->resumeAccepting();
}
情景是这样的:
客户已连接。所以,client = nextPendingConnection();
服务器暂停了收听。不接受新连接。
客户端已断开连接。需要释放client
。因此,client->deleteLater()
被调用。
服务器继续收听。
新的连接来了。所以,我需要client = nextPendingConnection();
但是,之前的client
对象已被删除?也许?也许不吧?在我在步骤5中为其分配新连接后,如果事件循环尝试删除client
该怎么办?
那么,如何删除以前断开连接的客户端,如何保留一个且只有一个客户端?
如果我这样做会安全吗?
void TcpServer::clientDisconnected()
{
QSocket* ptr = client;
ptr->deleteLater();
...
}
答案 0 :(得分:2)
我将引用有关它的Qt文档:
当控件返回事件循环时,对象将被删除。
所以deleteLater()
是延迟delete
。一旦调用deleteLater()
,该对象就被视为已删除。
您的nextPendingConnection()
电话会创建另一个需要稍后删除的对象。
但是在您的情况下,您只允许一个待处理的连接,并且在客户端断开连接之前不允许接受。在这种情况下,它应该是安全的,在其他情况下,您可能会覆盖您的客户端指针并将失去对它的控制(内存泄漏)。
即使在你的情况下,我也不愿意这个解决方案:
void TcpServer::clientDisconnected()
{
if (qobject_cast<QAbstractSocket*>(sender())) {
sender()->deleteLater();
}
...
}
如果在将来更改应用程序时允许多个连接,这也是安全的。
答案 1 :(得分:0)
据我了解,nextPendingConnection();
将返回指向新QTcpSocket
类对象的指针,因此您无需担心。
deleteLater()
将仅安排删除旧对象。 QTcpSocket* client
仅包含指向QTcpSocket
类对象的指针。当您调用deleteLater()
时,Qt将仅删除调用此函数时client
指向的对象。