打造您自己的专属QQ【附源码】(3)

说说关于QThread 的用法,tcpSocket起一个线程去读取用户注册信息这么一档子事。      

   

 

 

打造您自己的专属QQ【附源码】

线程,就是这么个模子:

TcpConThread::TcpConThread(int socketDescriptor, QObject *parent)           : QThread(parent), socketDescriptor(socketDescriptor)   {       ...   }      void TcpConThread::run()   {      ...   }   

备个注吧:QThread类提供了与系统无关的线程。

QThread代表在程序中一个单独的线程控制,在多任务操作系统中,它和同一进程中的其它线程共享数据,但运行起来就像一个单独的程序一样。它不是在main()中开始,QThread是在run()中开始运行的。你继承run()并且在其中包含你的代码。例如:

class MyThread : public QThread {          public:              virtual void run();          };          void MyThread::run()       {           forint count = 0; count < 20; count++ ) {               sleep( 1 );               qDebug( "Ping!" );           }       }          int main()       {           MyThread a;           MyThread b;           a.start();           b.start();           a.wait();           b.wait();       }  

Void QThread::run () [纯虚 保护]
这个方法是纯虚的,并且为了能够做有用的工作必须在继承类中被重新实现。这个方法的返回将会结束线程的执行。

void QThread::start ()
通过调用run()(必须在QThread子类中重新实现来包含你的代码)开始这个线程的执行。如果你试图开始一个已经运行的线程,这个调用将一直等待,直到这个线程完成,然后再重新开始这个线程。

void QThread::exit () [静态]

结束调用线程的执行并且唤醒任何等待它终止的线程。

 

bool QThread::wait ( unsigned long time = ULONG_MAX )

这将提供和POSIX pthread_join相似的功能。一个线程调用了它将会一直阻塞,知道下述条件之一满足时继续:

1.这个QThread对象所关联的线程已经结束执行(比如,当它从run()中返回)。如果线程完成,这个函数将返回真。如果线程还没有开始呢,这个函数也返回真。

2.time毫秒过去了。如果time是ULONG_MAX(默认值),然后等待将永远不会超时(线程必须从run()中返回)。如果等待时间到了,这个函数将返回假。 

想在线程里干什么,就在run()里写什么,在这里的实现很简单,内容都在on_Ready_Read()的实现里

void TcpConThread::run()   {          tcpSocket = new QTcpSocket;          connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(on_Ready_Read()));          if (!tcpSocket->setSocketDescriptor(socketDescriptor))       {           emit error(tcpSocket->error());           return;       }           exec();      }  

这个exec() 就是把整个进程空间换成要执行的那个程序的进程空间,说白了就把自己换成别人。

void TcpConThread::on_Ready_Read()   {       /*QString strLogin = tcpSocket->readAll();      QStringList strListUser = strLogin.split("|");      QString id = strListUser.at(0);      QString password = strListUser.at(1);*/          db = new SqliteDB;          QString ip = tcpSocket->peerAddress().toString();       qint16 port = tcpSocket->peerPort();          QByteArray block = tcpSocket->readAll();       QDataStream in(&block, QIODevice::ReadOnly);     //QDataStream in(tcpSocket);        quint16 dataGramSize;       QString msgType;       in >> dataGramSize >> msgType;          if ( "MSG_CLIENT_USER_REGISTER" == msgType )       {           QString id;           QString password;           QString name;           in >> id >> password >> name;              if ( 0 == db->insertNewUser( id, password, name, ip, QString::number(port)) )           {               QMessageBox::warning(NULL, tr("提示"), tr("该号码已被注册."));               QString msgType = "MSG_ID_ALREADY_EXIST";               QByteArray block;               QDataStream out(&block, QIODevice::WriteOnly);               out.setVersion(QDataStream::Qt_4_6);               out << (quint16)0 << msgType;               out.device()->seek(0);               out << (quint16)(block.size() - sizeof(quint16));               tcpSocket->write(block);           }           else           {               QByteArray block;                  QDataStream out(&block, QIODevice::WriteOnly);               out.setVersion(QDataStream::Qt_4_6);               QString msgType = "MSG_REGISTER_SUCCESS";               out << (quint16)0 << msgType;               out.device()->seek(0);               out << (quint16)(block.size() - sizeof(quint16));               tcpSocket->write(block);           }       }       else if ( "MSG_USER_LOGIN" == msgType )       {           QString id;           QString password;           in >> id >> password;           db->getUserInfo(id);              if (db->strListUser.isEmpty())        //MSG_ID_NOTEXIST            {                QMessageBox::critical(NULL, tr("提示"), tr("没有名字") );               QByteArray block;               QDataStream out(&block, QIODevice::WriteOnly);               out.setVersion(QDataStream::Qt_4_6);               QString msgType = "MSG_ID_NOTEXIST";               out << (quint16)0 << msgType;               out.device()->seek(0);               out << (quint16)(block.size() - sizeof(quint16));               tcpSocket->write(block);              }           else if(db->strListUser.at(1) != password)        //MSG_PWD_ERROR            {                  QByteArray block;               QDataStream out(&block, QIODevice::WriteOnly);               out.setVersion(QDataStream::Qt_4_6);               QString msgType = "MSG_PWD_ERROR";               out << (quint16)0 << msgType;               out.device()->seek(0);               out << (quint16)(block.size() - sizeof(quint16));               tcpSocket->write(block);           }           else if (db->strListUser.at(1) == password )           {               if ((db->strListUser.at(3)) == "1")          //MSG_LOGIN_ALREADY                {                      QByteArray block;                   QDataStream out(&block, QIODevice::WriteOnly);                   out.setVersion(QDataStream::Qt_4_6);                   QString msgType = "MSG_LOGIN_ALREADY";                   out << (quint16)0 << msgType;                   out.device()->seek(0);                   out << (quint16)(block.size() - sizeof(quint16));                   tcpSocket->write(block);                     }               else            //MSG_LOGIN_SUCCESS                {                   QByteArray block;                   QDataStream out(&block, QIODevice::WriteOnly);                   out.setVersion(QDataStream::Qt_4_6);                   QString msgType = "MSG_LOGIN_SUCCESS";                   out << (quint16)0 << msgType;                   out.device()->seek(0);                   out << (quint16)(block.size() - sizeof(quint16));                   tcpSocket->write(block);                   //login success, update database                    db->updateUserLogStat(id, "1");                   db->updateUserIp(id,tcpSocket->peerAddress().toString());               }              }       }  

还有请注意, QCoreApplication::exec() 必须从主线程(执行 main() 方法的线程)调用, 不从 QThread 调用。 在GUI应用程序,主线程也被称为GUI线程,因为它是唯一允许执行GUI相关操作的线程。

打造您自己的专属QQ源码下载:

相关文件下载地址在Linux公社的1号FTP服务器里,下载地址:

FTP地址:ftp://www.linuxidc.com

用户名:

密码:

在 2011年LinuxIDC.com\8月\打造您自己的专属QQ【附源码】

下载方法见这里

linux

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwdyyz.html