当前位置:编程学习 > wap >>

多线程,QTcpsocket问题!服务器断开时程序崩溃!

RT 请高手指教-谢谢帮忙!
我自己参照网上的一些资料写了个QTcpSocket的线程!当我连接到服务器后,然后让服务器断开连接,程序有时候就正常,但是大多数情况下程序就崩溃!
错误信息如下图:
[img=http://www.qtcn.org/bbs/attachment/Mon_1203/62_116608_b5250f5c9029d54.jpg?176][/img]
就是d这个参数有问题!  
  if (d->socketEngine)
        d->socketEngine->setReadNotificationEnabled(false); 执行完这句就挂了!!


我尝试过用Designer进行编译,MinGw进行编译,并且今天我还更新了新的QT4.8.1(以前是4.8.0),都是崩溃,一会儿就好了!
我把链接socket状态信号和自定义槽,注释掉后,就留下发射数据的信号,就没有任何问题!如下:

1.//connect(socketClient, SIGNAL(connected()),this, SLOT(sendRequest())); 
2.//connect(socketClient, SIGNAL(disconnected()), this,SLOT(connectionCloseByServer())); 
3.connect(socketClient, SIGNAL(readyRead()), this, SLOT(recvdatagram()),Qt::DirectConnection); 
4.//connect(socketClient, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(error())); 


所以我怀疑我的代码写的有问题,请各位高手指点!!
SocketThread.h 


1.#ifndef SOCKETTHREAD 
2.#define SOCKETTHREAD 
3.
4.#include <QtNetwork/QtNetwork> 
5.#include <QThread> 
6.
7.
8.class SocketThread : public QThread 
9.{ 
10.Q_OBJECT 
11.
12.//function 
13.public: 
14.SocketThread(QHostAddress addr, int port); 
15.~SocketThread(); 
16.//通过该函数删除socket 
17.void Stop(); 
18.
19.// variable 
20.public: 
21.
22.//variable 
23.private: 
24.
25.int sum; 
26.bool needStopThread; 
27.QTcpSocket *socketClient; 
28.quint16 readBufferSize; 
29.quint16 nextBlockSize; 
30.QByteArray datagram; 
31.
32.QHostAddress _hostAddress; 
33.int _portNumber; 
34.
35.//function 
36.private: 
37.void closeConnection(); 
38.
39.private slots: 
40.void sendRequest(); 
41.void connectionCloseByServer(); 
42.void error(); 
43.void recvdatagram(); 
44.signals: 
45.//将接收到的数据和状态发射出去! 
46.void RecvDateDisplay(QByteArray str); 
47.void SumDisplay(int s); 
48.void disButtonDisplay(bool b); 
49.void conButtonDisplay(bool a); 
50.void proBarDisplay(bool a); 
51.void staLabeDisplay(QString str); 
52.
53.protected: 
54.virtual void run(); 
55.}; 
56.#endif //SOCKETTHREAD


SocketThread.cpp


1.#include "SocketThread.h" 
2.#include <QtGui> 
3.
4.SocketThread::SocketThread(QHostAddress addr, int port) 
5.{ 
6._hostAddress =addr; 
7._portNumber = port; 
8.sum = 0; 
9.needStopThread = false; 
10.socketClient=NULL; 
11.readBufferSize = 256; 
12.
13.qRegisterMetaType<QAbstractSocket::SocketError>("QAbstractSocket::SocketError"); 
14.} 
15.SocketThread::~SocketThread() 
16.{ 
17.needStopThread = false; 
18.closeConnection(); 
19.quit(); 
20.wait(); 
21.} 
22.
23.void SocketThread::sendRequest() 
24.{ 
25.emit staLabeDisplay(tr("Connected!")); 
26.emit proBarDisplay(false); 
27.} 
28.void SocketThread::connectionCloseByServer() 
29.{ 
30.if (nextBlockSize != 0xFFFF) 
31.{ 
32.emit staLabeDisplay(tr("Error:connection closed by server")); 
33.emit proBarDisplay(false); 
34.} 
35.
36.if (socketClient) 
37.{ 
38.socketClient->close(); 
39.exit(); 
40.wait(); 
41.} 
42.
43.} 
44.void SocketThread::error() 
45.{ 
46.emit staLabeDisplay(socketClient->errorString()); 
47.emit proBarDisplay(false); 
48.emit conButtonDisplay(true); 
49.emit disButtonDisplay(false); 
50.
51.if (socketClient) 
52.{ 
53.socketClient->close(); 
54.exit(); 
55.wait(); 
56.} 
57.} 
58.void SocketThread::run() 
59.{ 
60.
61.nextBlockSize = 0; 
62.
63.socketClient = new QTcpSocket; 
64.
65.if (!_hostAddress.isNull() && _portNumber >0) 
66.{ 
67.socketClient->abort(); 
68.socketClient->connectToHost(_hostAddress, _portNumber, QIODevice::ReadOnly); 
69.socketClient->setReadBufferSize(readBufferSize); 
70.emit staLabeDisplay(tr("Connect to Server........")); 
71.emit proBarDisplay(true); 
72.emit conButtonDisplay(false); 
73.emit disButtonDisplay(true); 
74.} 
75.//slot 
76.
77.connect(socketClient, SIGNAL(connected()),this, SLOT(sendRequest())); 
78.connect(socketClient, SIGNAL(disconnected()), this,SLOT(connectionCloseByServer())); 
79.connect(socketClient, SIGNAL(readyRead()), this, SLOT(recvdatagram()),Qt::DirectConnection); 
80.connect(socketClient, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(error())); 
81.
82.
83.exec(); 
84.while(needStopThread) 
85.{ 
86.if (socketClient) 
87.{ 
88.closeConnection(); 
89.} 
90.break; 
91.} 
92.
93.} 
94.void SocketThread::closeConnection() 
95.{ 
96.socketClient->abort(); 
97.socketClient->close(); 
98.delete socketClient; 
99.socketClient = NULL; 
100.
101.sum =0; 
102.emit proBarDisplay(false); 
103.emit conButtonDisplay(true); 
104.emit disButtonDisplay(false); 
105.} 
106.void SocketThread::Stop() 
107.{ 
108.needStopThread = true; 
109.} 
110.void SocketThread::recvdatagram() 
111.{ 
112.if (socketClient->bytesAvailable() >0) 
113.{ 
114.datagram.resize(socketClient->bytesAvailable()); 
115.socketClient->read(datagram.data(), datagram.size()); 
116.sum = sum +datagram.size(); 
117.
118.emit SumDisplay(sum); 
119.emit RecvDateDisplay(datagram); 
120.} 
121.} --------------------编程问答-------------------- LZ的代码太长太乱,就不看了
我写过一个多线程QTcpsocket的小例子,LZ可以参考一下:
http://blog.csdn.net/aaa20090987/article/details/6789562

希望能帮到你。 --------------------编程问答-------------------- 我是用QThread开了一个QTcpSocket的线程,负责接收服务器端发出的数据,
然后把接收到的数据 用signal void RecvDateDisplay(QByteArray str);发射给主的GUI界面进行显示。  
以下几个函数就是负责,把QTcpsocket的状态拿出来,发射给GUI!
connect(socketClient, SIGNAL(connected()),this, SLOT(sendRequest()));  
connect(socketClient, SIGNAL(disconnected()), this,SLOT(connectionCloseByServer()));  
connect(socketClient, SIGNAL(readyRead()), this, SLOT(recvdatagram()),Qt::DirectConnection);  
connect(socketClient, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(error()));  

其他状态都是正常的,主动断开,连接超时,都是对的。就是服务器主动断开,我的程序就停在QAbstractSocket中了-如上图,我想去进行调试都没有办法!
你的例子注重的是多线程服务器,我也看了,手头也有多线程服务器相关的书籍,所以想请您给我指点下我的程序!
十分感谢! --------------------编程问答-------------------- 问题的原因找到了!应该采用阻塞式通信方式,参照Qt自带的例子,Blocking Fortune Client Example
就没有问题!! --------------------编程问答-------------------- --------------------编程问答-------------------- 谢谢楼主的分享,我今天也碰到了同样的问题
补充:移动开发 ,  Qt
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,