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

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

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

3. 使用socket进行通信;

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

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

  1. TcpNetwork::TcpNetwork()
  2. {
  3. ...
  4. connect(mySocket, SIGNAL(disconnect(QTcpSocket*)), this, SLOT(ServerConnectionLost(QTcpSocket*)));
  5. ...
  6. }
  1. TcpNetwork::~TcpNetwork()
  2. {
  3. if (tcpServer != NULL)
  4. {
  5. delete tcpServer;
  6. }
  7. }
  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的释放的一个需要注意的情况(必须先断开连接)的更多相关文章

  1. 【原创】高性能网络编程(二):上一个10年,著名的C10K并发连接问题

    1.前言 对于高性能即时通讯技术(或者说互联网编程)比较关注的开发者,对C10K问题(即单机1万个并发连接问题)应该都有所了解."C10K"概念最早由Dan Kegel发布于其个人 ...

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

    mysql中添加一个和root一样的用户用于远程连接: 大家在拿站时应该碰到过.root用户的mysql,只可以本地连,对外拒绝连接. 下面语句添加一个新用户administrtor: CREATE ...

  3. 在spring中如何生成一个bean (一个对象,比如jedis的连接池对象)【我】

    在spring中,要想生成一个单例对象(比如jedis的连接池对象) 方法1: 在 spring中用 bean 标签生成(反正就是让spring生成并管理单例的对象) 方法2: 把要生成的单例对象类, ...

  4. Spring Boot中一个Servlet主动断开连接的方法

    主动断开连接,从而返回结果给客户端,并且能够继续执行剩余代码. 对于一个HttpServletResponse类型的对象response来说,执行如下代码: response.getWriter(). ...

  5. 建立一个可以不停地接收客户端新的连接,但不能处理复杂的业务的C/S网络程序

    在Windows平台上主要有两个版本的Socket Api函数:WinSock 1.1和WinSock 2.2 , 2.2版本默认兼容1.1版本,1.1 winsock.h wsock32.lib w ...

  6. 正确释放WORD对象(COM组件) COMException: 被调用的对象已与其客户端断开连接

    本来form method=post本页面 修改为其他页面 action=save.aspx后没问题 其他问题可参考以下: 引自:http://topic.csdn.net/u/20090108/17 ...

  7. 在远程连接一个 Wndows 10的情况下,重启远程机器

    如果你从菜单找的话,是找不到这个菜单的!!! 你应该直接按 alt + F4 , 就会出现这个选项了. 参考: https://tommynation.com/shut-windows-10-remo ...

  8. Linux查看某一个端口监听情况

    1.使用lsof   lsof -i:端口号查看某个端口是否被占用 2.使用netstat 使用netstat -anp|grep 80 

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

    提问者采纳   很简单 只要把你要共享的连接 192.168.0.1 0改成1 然后就可以共享了 共享后再改回来 就能上了 但是会出现IP冲突的~

随机推荐

  1. Android自己定义控件2-简单的写字板控件

    概述 上一篇文章我们对自己定义控件进行了一个大体的知识介绍. 今天就来学习自己定义一个简单的写字板控件. 先来看看效果图 就是简单的依据手指写下的轨迹去画出内容 实现 在上一篇文章里提到了androi ...

  2. 【Bash百宝箱】Linux shell学习

    shell特点-- Linux有多种shell能够使用,默认的为bash,bash有以下几个主要特点. 1.命令记忆能力 在命令行中按上下键能够找到一个前/后输入的命令.这些命令记录在-/.bash_ ...

  3. GCD网络多线程---同步运行,异步运行,串行队列,并行队列

    总结:同步(无论是串行还是并行)----不又一次开辟子线程 异步(无论是串行还是并行)----开辟子线程 GCD: dispatch queue 主线程的main queue 并行队列 global ...

  4. ubuntu系统安装和配置

    1.分区信息 1.1 /boot分区 这个分区包括了操作系统的内核和在启动系统过程中所要用到的文件.假设有了一个单独的/boot启动分区,即使基本的根分区出现了问题,计算机依旧可以启动.这个分区的大小 ...

  5. C 语言 —— ! 和 ~(感叹号和波浪号)

    ~ 表示按位取反,是位运算符,运算对象是 2 进制. !表示逻辑非,是逻辑运算符,运算对象是真或假.最终的结果也是 0/1 !!:则表示取过一次非之后,再取一次: !!5 ⇒ 1

  6. 使用SecureCRT连接AWS的EC2

    如果使用CentOS等linux系统,直接使用ssh命令即可访问AWS上的Linux-EC2实例. $ ssh -i XXX.pem ec2-user@{IP/hostname} 在Windows系统 ...

  7. iOS BCD编码

    inline static NSData* encodeBCD(NSString *value){ //NSString *value = @"123456"; NSMutable ...

  8. ANR问题分析实例

    ANR监测机制包含三种: Service ANR,前台进程中Service生命周期不能超过20秒,后台进程中Service的生命周期不能超过200秒. 在启动Service时,抛出定时消息SERVIC ...

  9. C#委托之个人理解

    C#委托之个人理解   什么是委托 首先要知道什么是委托,用最通俗易懂的话来讲,你就可以把委托看成是用来执行方法(函数)的一个东西. 如何使用委托 在使用委托的时候,你可以像对待一个类一样对待它.即先 ...

  10. Android Studio 报错Guest isn't online after 7 seconds 解决方案

     最近使用真机模拟之后,再使用虚拟机就频繁出现这个问题; 解决步骤如下: 1.打开Android虚拟设备管理器, 2.查看Actoins栏下拉图标, 3.选择冷启动模式即可, 4.重启AVD正常;