关于QSocket的释放的一个需要注意的情况(必须先断开连接)

Posted 朝闻道

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于QSocket的释放的一个需要注意的情况(必须先断开连接)相关的知识,希望对你有一定的参考价值。

最近在用QtNetwork编写服务器程序进行TCP/IP通信,大体过程如下:

1. 创建一个QTcpServer实例,监听目标IP和端口;

2. 一旦监听到有连接,获取和客户端之间的socket;

3. 使用socket进行通信;

4. 通信结束后,可以手动释放socket,也可以不管它,在释放QTcpServer的时候会把其下的所有socket全部自动释放。

 

在编写时,我做了如下事:

 

[cpp] view plain copy
 
  1. TcpNetwork::TcpNetwork()  
  2. {  
  3.     ...  
  4.     connect(mySocket, SIGNAL(disconnect(QTcpSocket*)), this, SLOT(ServerConnectionLost(QTcpSocket*)));  
  5.     ...  
  6. }  

 

 

[cpp] view plain copy
 
  1. TcpNetwork::~TcpNetwork()  
  2. {  
  3.     if (tcpServer != NULL)  
  4.     {  
  5.         delete tcpServer;  
  6.     }  
  7. }  
[cpp] view plain copy
 
  1. <pre name="code" class="cpp">void TcpNetwork::ServerConnectionLost(QTcpSocket *socket)  
  2. {     
  3.     if (socket == mySocket)  
  4.     {  
  5.         ...  
  6.         // debug  
  7.         delete mySocket;  
  8.         mySocket = NULL;  
  9.         ...  
  10.     }  
  11. }  



 


 

 

这样在关闭程序窗口时会导致崩溃,看了一下QTcpServer的析构函数源码后发现,在析构时Qt会首先检查QtcpServer下的socket指针所指向内存是否已被释放,然后执行每个socket的关闭操作,随后释放刚才被检查过的未被释放的socket内存,最后释放QTcpServer。

 

如果将QTcpSocket::disconnect()信号与一个其中带有释放socket操作的槽连接起来,那么如果socket还没有关闭就直接析构QTcpServer,在执行断开socket这一步时(如果之前已经断开了就不会再执行这一步了)会触发带有删除socket操作的槽,然而析构函数对此一无所知,紧接着便是析构函数来释放socket,也就造成了socket的内存的重复释放,导致崩溃。

 

解决方法:在关闭窗口之前先关闭socket,这样在析构函数中就不会再执行关闭socket的操作。或者在连接断开时触发的含有释放socket操作的槽中将delete socket改为socket->deleteLater()。

 

http://blog.csdn.net/qq_19672579/article/details/47973409

以上是关于关于QSocket的释放的一个需要注意的情况(必须先断开连接)的主要内容,如果未能解决你的问题,请参考以下文章

近期在制作QSocket类,实现对Linuxunix 下的Socket的封装

注意锁标记是自己不会自动释放,必须有通知

[转]ViewController的生命周期

具有大量自动释放对象的线程如果是/否,在这种情况下是不是必须使用自动释放池,为啥?

关于java内存释放的问题

verilog|关于异步复位,同步释放的几个思考