关于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

时间: 2024-10-12 22:44:40

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

关于QSocket的释放的一个需要注意的情况

最近在用QtNetwork编写服务器程序进行TCP/IP通信,大体过程如下: 1. 创建一个QTcpServer实例,监听目标IP和端口: 2. 一旦监听到有连接,获取和客户端之间的socket: 3. 使用socket进行通信: 4. 通信结束后,可以手动释放socket,也可以不管它,在释放QTcpServer的时候会把其下的所有socket全部自动释放. 在编写时,我做了如下事: TcpNetwork::TcpNetwork() { ... connect(mySocket, SIGNAL

无法启动INTERNET连接共享。一个已经用IP地址配置的LAN连接需要自动IP地址

提问者采纳 很简单 只要把你要共享的连接 192.168.0.1 0改成1 然后就可以共享了 共享后再改回来 就能上了 但是会出现IP冲突的~ 无法启动INTERNET连接共享.一个已经用IP地址配置的LAN连接需要自动IP地址

mysql中添加一个和root一样的用户用于远程连接

mysql中添加一个和root一样的用户用于远程连接: 大家在拿站时应该碰到过.root用户的mysql,只可以本地连,对外拒绝连接. 下面语句添加一个新用户administrtor: CREATE USER 'monitor'@'%' IDENTIFIED BY 'admin'; GRANT ALL PRIVILEGES ON *.* TO 'monitor'@'%' IDENTIFIED BY 'admin' WITH GRANT OPTION MAX_QUERIES_PER_HOUR 0

指定的元素已经是另一个元素的逻辑子元素。请先将其断开连接。(解决问题总结)

起因: <Window x:Class="WpfApplication1.Window3" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Window3" Height="300" Width=

[ASP.NET]EF选一个空表的情况

public List<DAL.StuFillAnswers> FillsToCheck(int sid,int eid) { using (DAL.ExamSysEntities db = new DAL.ExamSysEntities()) { return db.StuFillAnswers.Where(x => x.StuID == sid && x.ExamID == eid).ToList(); } } 返回的是count为0的list [ASP.NET]EF

一个根据内存使用情况重启tomcat的小脚本

有一台服务器上部署了tomcat,随着时间的推移,内存消耗越来越大,所以写了一个小脚本配合crontab定时检测内存,不足的情况下重启tomcat. #!/bin/bash #tomcat restart:out of memory LOG=./restart_tomcat.log TOMCAT=/tomcat/bin/ TOMCATDIR=/tomcat echo"----------------------------" >> $LOG mem_total=$(free

读取多行数据,每行存放一个位置。:读取通过wps模式连接到设备的信息。

数据的情况是按行存放,行数读取前不固定. 我这个实现方式不一定是最简单方便的,希望有更好的解决方式的网友留言告之- 当连接一个设备上来的时候是这种,两个如下叠加. ff:ff:ff:ff:ff:ff dot11RSNAStatsSTAAddress=ff:ff:ff:ff:ff:ff dot11RSNAStatsVersion=1 dot11RSNAStatsSelectedPairwiseCipher=00-0f-ac-4 dot11RSNAStatsTKIPLocalMICFailures=

【原创】一个普适于各种情况易于操作的高可用服务器部署方案

一个大型的互联网系统,采用负载均衡原理实现高可用是最基本的要求,几年前,要想做到这点,得是大公司,找牛逼的技术员才行,现在,阿里云出来之后,门槛极大降低,让运营方可以全心去做运营,不用再为技术方面考虑太多,下图是一个比较典型的利用阿里云提供的各项服务,搭建的一个可水平扩展的部署方案. 这个方案有以下特点: 1.技术难度不高 一般来说,只需要对session和文件保存这两块的代码稍作修改,实现集中存取即可 2.成本费用低 充分利用阿里云的可灵活升级策略,根据系统负载,逐步升级配置 3.达成高可用

三种方式实例化一个类的性能情况

源内容:http://www.cnblogs.com/shouce/p/5558095.html#undefined 下面的内容是根据“源内容”进行了整改.补充. 三种方式实例化一类,包括无参数构造形式与有参数构造形式性能测试. 使用new关键字创建类实例(常用方式). 使用Activator激活器类创建类实例(Activator用以在本地或从远程创建对象类型,或获取对现有远程对象的引用). 使用Assembly程序集创建类实例(Assembly表示一个程序集,它是一个可重用.无版本冲突并且可自