救命!!求助!!有个关于QTcpSocket的奇怪问题

zch128 2010-09-23 07:46:17
用QT4在做一个服务器端连接多个客户端的程序,每个客户端连接过来以后都建立一个线程,每个线程里维护一个QTcpSocket.
现在发现一个难以解决的问题:如果服务向客户端发送了数据以后,disconnected()和erro(QAbstractSocket::SocketError)消息就收不到了!!!服务器一直以为这个连接是正确的,服务器再向这个断开的连接发送3次消息,就崩溃!!
如果改成单线程的话这种现象就没有,这次是我第一次做QT,真的搞不定了,请大侠们务必帮帮我啊!!!!!
...全文
385 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
gogo106 2010-09-24
  • 打赏
  • 举报
回复
我也没搞懂!
lefttime 2010-09-24
  • 打赏
  • 举报
回复
感觉问题出现在客户端消息处理, LZ能描述下你的客户端的消息接收和发送是如何连接的么?
zch128 2010-09-24
  • 打赏
  • 举报
回复
我发现是多线程的问题,如果在单线程的情况下就没有问题,可是为什么我想不明白
zch128 2010-09-24
  • 打赏
  • 举报
回复

#ifndef CSERVER_H
#define CSERVER_H

#ifndef QT_THREAD_SUPPORT
#define QT_THREAD_SUPPORT
#endif

#include <Vector>
#include <QTNetwork>

class CServer;
class CTcpServerDlg;

class CConnect : public QThread
{
Q_OBJECT

public:
CConnect(CServer* pServer_, int nDesp_);
~CConnect();

bool m_bSelect;
QString m_strName;
QString m_strMsg;

int m_nDesp;
CServer* m_pServer;
QTcpSocket* m_pSocket;

void run();

public slots:
void ProReadyRead();
void ProWrite(CConnect* pConn, QString str_);
void ProDisconnect();
void ProError(QAbstractSocket::SocketError error_);
void deleteLater();

signals:
void send(CConnect* pConn_, QString str_, QString strMsg_);
void Disconn(CConnect* pConn_, bool bError_);
};

enum MSGType
{
MSG_NONE,
MSG_CONN,
MSG_DISCONN,
MSG_LOSTCONN,
MSG_RECEIVE,
};

class CServer : public QTcpServer
{
Q_OBJECT

public:
CServer(QObject *parent = 0);
~CServer();

signals:
void ReFresh();
void WriteConn(CConnect* pConn, QString str_);

public slots:
void ReadConn(CConnect* pConn_, QString strName_, QString strMsg_);
void RemoveConnect(CConnect* pConn_, bool bError_);

public:
bool Start(int nPort_);
void incomingConnection(int socketDescriptor);
void SendInfo(const QString& str_, const QList<int>& list_);
void SendInfo(CConnect* pConn_, const QString& str_);

QString m_strMessage;
QString m_strName;

MSGType m_nType;


std::vector<CConnect*> m_pConVector;
};

bool Prase(char* pBuf_, qint64 nCount_,
QString& strName_, QString& strMsg_);
#endif
以上是.cpp和.h
zch128 2010-09-24
  • 打赏
  • 举报
回复

#include <CServer.h>
#define BUF_MAX 10240
CConnect::CConnect(CServer* pServer_, int nDesp_)
: QThread(pServer_)
{
m_pServer = pServer_;
m_bSelect = false;
m_pSocket = 0;
m_nDesp = nDesp_;
m_strName = "Unknow";

connect(this, SIGNAL(send(CConnect*, QString, QString)), m_pServer,
SLOT(ReadConn(CConnect*, QString, QString)));

connect(this, SIGNAL(Disconn(CConnect*, bool)), m_pServer, SLOT(RemoveConnect(CConnect*, bool)));
}

CConnect::~CConnect()
{}

void CConnect::run()
{
m_pSocket = new QTcpSocket(this);
m_pSocket->setSocketDescriptor(m_nDesp);

connect(m_pSocket, SIGNAL(readyRead()), this, SLOT(ProReadyRead()));

connect(m_pSocket, SIGNAL(disconnected()), this, SLOT(ProDisconnect()));
connect(m_pSocket, SIGNAL(error(QAbstractSocket::SocketError)),
this, SLOT(ProError(QAbstractSocket::SocketError)));
exec();
}

void CConnect::deleteLater()
{
if (m_pSocket)
m_pSocket->deleteLater();
QThread::deleteLater();
}
void CConnect::ProReadyRead()
{
assert(m_pSocket);

qint64 _nCount = m_pSocket->bytesAvailable();

if (_nCount <= 0)
return;

assert(_nCount <= BUF_MAX);

char _buff[BUF_MAX];
memset(_buff, 0, sizeof(_buff));
m_pSocket->read(_buff, _nCount);

QString _strName, _strMsg;
if (Prase(_buff, _nCount, _strName, _strMsg))
emit send(this, _strName, _strMsg);
}

void CConnect::ProWrite(CConnect* pConn, QString str_)
{
if (pConn == this && str_.length() &&
isRunning() && m_pSocket->isValid())

m_pSocket->write(str_.toAscii().data());
}

void CConnect::ProDisconnect()
{
quit();
emit Disconn(this, false);
deleteLater();
}

void CConnect::ProError(QAbstractSocket::SocketError)
{
quit();
emit Disconn(this, true);
deleteLater();
}

CServer::CServer(QObject *parent)
: QTcpServer(parent)
, m_nType(MSG_NONE)
{}

CServer::~CServer()
{
for(std::vector<CConnect*>::iterator _iter = m_pConVector.begin();
_iter != m_pConVector.end(); _iter++)
{
CConnect* _pConn = (CConnect*)(*_iter);
if (_pConn->isRunning())
_pConn->quit();

_pConn->deleteLater();
}
close();
}

bool CServer::Start(int nPort_)
{
assert(nPort_ > 0);
return listen(QHostAddress::Any, nPort_);
}

void CServer::SendInfo(const QString& str_, const QList<int>& list_)
{
assert(list_.count() == m_pConVector.size());
for (int _i = 0; _i < list_.count(); _i++)
emit WriteConn(m_pConVector[list_[_i]], str_);
}

void CServer::SendInfo(CConnect* pConn_, const QString& str_)
{
emit WriteConn(pConn_, str_);
}

void CServer::incomingConnection(int socketDescriptor)
{
CConnect* _pConnect = new CConnect(this, socketDescriptor);

m_nType = MSG_CONN;
m_strMessage = "";
m_strName = _pConnect->m_strName;

m_pConVector.push_back(_pConnect);
emit ReFresh();
_pConnect->start();
}

void CServer::ReadConn(CConnect* pConn_, QString strName_, QString strMsg_)
{
pConn_->m_strName = strName_;

m_nType = MSG_RECEIVE;
m_strMessage = strMsg_;
m_strName = strName_;

emit ReFresh();
}

void CServer::RemoveConnect(CConnect* pConn_, bool bError_)
{
assert(pConn_);
for(std::vector<CConnect*>::iterator _iter = m_pConVector.begin();
_iter != m_pConVector.end(); _iter++)
{
if (*_iter == pConn_)
{
m_pConVector.erase(_iter);

m_nType = bError_ ? MSG_LOSTCONN : MSG_DISCONN;
m_strMessage = "";
m_strName = pConn_->m_strName;

//delete pConn_;
emit ReFresh();
return;
}
}
}

bool Prase(char* pBuf_, qint64 nCount_,
QString& strName_, QString& strMsg_)
{
char* _p1 = strstr(pBuf_, "GET");
char* _p2 = strstr(pBuf_, ",");
char* _p3 = strstr(pBuf_, "#");

if (!_p1 || !_p2 || !_p3 || _p2 - _p1 <= 3
|| _p3 - _p2 <= 1)
return false;

*_p2 = 0;
*_p3 = 0;

strName_ = _p1 + 3;
strMsg_ = _p2 + 1;

assert(!(strName_.isEmpty() &&
strMsg_.isEmpty()));
return true;
}
dext 2010-09-24
  • 打赏
  • 举报
回复
是不是客户端 自己关了,我以前就犯过这样的错误。

16,203

社区成员

发帖
与我相关
我的任务
社区描述
Qt 是一个跨平台应用程序框架。通过使用 Qt,您可以一次性开发应用程序和用户界面,然后将其部署到多个桌面和嵌入式操作系统,而无需重复编写源代码。
社区管理员
  • Qt
  • 亭台六七座
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧