在deleteLater之后,我可以再次使用QTcpSocket进行另一次连接吗?

时间:2015-09-16 07:06:42

标签: c++ qt

我尝试使用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();
}

情景是这样的:

  1. 客户已连接。所以,client = nextPendingConnection();

  2. 服务器暂停了收听。不接受新连接。

  3. 客户端已断开连接。需要释放client。因此,client->deleteLater()被调用。

  4. 服务器继续收听。

  5. 新的连接来了。所以,我需要client = nextPendingConnection();

  6. 但是,之前的client对象已被删除?也许?也许不吧?在我在步骤5中为其分配新连接后,如果事件循环尝试删除client该怎么办?

    那么,如何删除以前断开连接的客户端,如何保留一个且只有一个客户端?

    如果我这样做会安全吗?

    void TcpServer::clientDisconnected()
    {
        QSocket* ptr = client;
        ptr->deleteLater();
        ...
    }
    

2 个答案:

答案 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指向的对象。