Qt编写的软件在线升级系统(服务器端)

给公司开发的软件,每次更新后都要一个个的去帮使用的同事重新安装,很麻烦,所以放下几个bug没有解决,先写了一个升级的小程序。

 

程序入口(main.cpp):

[cpp]  view plain  copy
  1. #include <QtCore>  
  2. #include <QCoreApplication>  
  3. #include <QDebug>  
  4. #include <QTextCodec>  
  5. #include "Server.h"  
  6. int main(int argc, char *argv[])  
  7. {  
  8.     QCoreApplication a(argc, argv);  
  9.     QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));  
  10.     QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));  
  11.     qDebug()<<"CR_MRP_update:Welcome to ChuangRen MRP/nCR_MRP_Update:Update Server starting...";  
  12.     Server *server=new Server();  
  13.     server->listenConnect();  
  14.     return a.exec();  
  15. }  

 

在主程序中先设置了软件的编码,然后启动一个服务器并监听连接。服务器类的定义如下(Server.h):

 

[cpp]  view plain  copy
  1. /* 
  2.  * Server.h 
  3.  * 
  4.  *  Created on: 2009-5-7 
  5.  *      Author: 于成文 
  6.  */  
  7. #ifndef SERVER_H_  
  8. #define SERVER_H_  
  9. #include <QDebug>  
  10. #include <QTcpServer>  
  11. #include <QTcpSocket>  
  12. #include <QHostAddress>  
  13. #include <QFile>  
  14. #include <QByteArray>  
  15. #include "ConnectThread.h"  
  16. class Server : public QTcpServer{  
  17.     Q_OBJECT  
  18. public:  
  19.     Server(QObject *parent=0);  
  20.     ~Server();  
  21.     bool listenConnect();  
  22. private slots:  
  23.     void incomingConnection(int socketId);  
  24. private:  
  25.     QString version;    //服务器上的最新版本  
  26.     QByteArray file1,file2; //保存客户端要更新的文件  
  27. };  
  28. #endif /* SERVER_H_ */  

 

下面是Server类的实现(Server.cpp):

 

[cpp]  view plain  copy
  1. /* 
  2.  * Server.cpp 
  3.  * 
  4.  *  Created on: 2009-5-7 
  5.  *      Author: 于成文 
  6.  */  
  7. #include "Server.h"  
  8. Server::Server(QObject *parent):QTcpServer(parent)  
  9. {  
  10.     QFile file("version.dat");  
  11.     if (file.open(QIODevice::ReadOnly))  
  12.     {  
  13.         QTextStream stream(&file);  
  14.         version = stream.readLine();  
  15.         file.close();  
  16.     }  
  17.     QFile upfile1("MRP.exe");  
  18.     QFile upfile2("common.dll");  
  19.     if (upfile1.open(QIODevice::ReadOnly)&&upfile2.open(QIODevice::ReadOnly))  
  20.     {  
  21.         file1=upfile1.readAll();  
  22.         file2=upfile2.readAll();  
  23.     }  
  24. }  
  25. Server::~Server() {  
  26. }  
  27. /** 
  28.  * 开始监听 
  29.  */  
  30. bool Server::listenConnect()  
  31. {  
  32.     if(!this->listen(QHostAddress::Any,3327))  
  33.     {  
  34.         qDebug()<<"CR_MRP_Update:listen on port 3327 failed!";  
  35.         this->close();  
  36.         return false;  
  37.     }  
  38.     qDebug()<<"CR_MRP_Update:listen on port 3327,waiting connection...";  
  39.     return true;  
  40. }  
  41. /** 
  42.  * 当有客户端连接时运行此函数 
  43.  */  
  44. void Server::incomingConnection(int socketId)  
  45. {  
  46.     qDebug()<<"/nCR_MRP_Update:a client try to connect...";  
  47.     //连接客户端  
  48.     ConnectThread * thread = new ConnectThread(this,socketId,version,file1,file2);  
  49. }  

 

在Server类的构造函数中读取了当前服务器上的客户端软件的版本信息,并将客户端读入内存。当有客户端连接是会自动运行函数incomingConnection(int socketId),这个函数中初始化了一个ConnectThread类的对象,并将各种信息通过构造函数传递给它。
下面是类ConnectThread的定义和实现():

 

[cpp]  view plain  copy
  1. /* 
  2.  * ConnectThread.h 
  3.  * 
  4.  *  Created on: 2009-5-7 
  5.  *      Author: 于成文 
  6.  */  
  7. #ifndef CONNECTTHREAD_H_  
  8. #define CONNECTTHREAD_H_  
  9. #include <QDebug>  
  10. #include <QTcpSocket>  
  11. #include <QDataStream>  
  12. #include <QDate>  
  13. #include <QByteArray>  
  14. #include <QFile>  
  15. class ConnectThread : public QObject  
  16. {  
  17.     Q_OBJECT  
  18. public:  
  19.     ConnectThread(QObject * parent = 0 ,int socketId=0,const QString &version="",QByteArray file1=0,QByteArray file2=0);  
  20.     ~ConnectThread();  
  21. private:  
  22.     int socketId;  
  23.     QTcpSocket *clientSocket;  
  24.     quint64 nextBlockSize;  
  25.     QString version;  
  26.     QByteArray file1,file2;  
  27. private slots:  
  28.     void threadOver();  
  29.     void communicate();  
  30. };  
  31. #endif /* CONNECTTHREAD_H_ */  

 

 

[cpp]  view plain  copy
  1. /* 
  2.  * ConnectThread.cpp 
  3.  * 
  4.  *  Created on: 2009-5-7 
  5.  *      Author: 于成文 
  6.  */  
  7. #include "ConnectThread.h"  
  8. ConnectThread::ConnectThread(QObject * parent,int socketId,const QString &version,QByteArray file1,QByteArray file2)  
  9. {  
  10.     nextBlockSize=0;  
  11.     clientSocket=new QTcpSocket(this);  
  12.     clientSocket->setSocketDescriptor(socketId);  
  13.     this->version=version;  
  14.     this->file1=file1;  
  15.     this->file2=file2;  
  16.     connect(clientSocket, SIGNAL(disconnected()),this, SLOT(threadOver()));  
  17.     connect(clientSocket,SIGNAL(readyRead()),this,SLOT(communicate()));  
  18.     qDebug()<<"CR_MRP_Update:connect to server successful,client id is"<<socketId;  
  19.     //发送当前服务器上的客户端版本信息给升级客户端  
  20.     QByteArray block;  
  21.     QDataStream out(&block, QIODevice::WriteOnly);  
  22.     out.setVersion(QDataStream::Qt_4_5);  
  23.     out<<quint64(0)<<quint16(0x0001)<<version;  
  24.     out.device()->seek(0);  
  25.     out<<quint64(block.size()-sizeof(quint16));  
  26.     clientSocket->write(block);  
  27. }  
  28. ConnectThread::~ConnectThread() {  
  29. }  
  30. /** 
  31.  * 和客户端通信 
  32.  */  
  33. void ConnectThread::communicate()  
  34. {  
  35.     //创建数据流  
  36.     QDataStream in(clientSocket);  
  37.     in.setVersion(QDataStream::Qt_4_5);  
  38.     while(1)  
  39.     {  
  40.         if (nextBlockSize == 0)  
  41.         {  
  42.             if (clientSocket->bytesAvailable() < sizeof(quint64))  
  43.             {  
  44.                 break;  
  45.             }  
  46.             in >> nextBlockSize;  
  47.         }  
  48.         if ((quint64)(clientSocket->bytesAvailable())<nextBlockSize)  
  49.         {  
  50.             break;;  
  51.         }  
  52.         quint16 protocol;  
  53.         in>>protocol;  
  54.         qDebug()<<"CR_MRP_Update:protocol:"<<QString::number(protocol,16);  
  55.         if(protocol==1)  
  56.         {  
  57.             //升级  
  58.             QByteArray fblock;  
  59.             QDataStream fout(&fblock, QIODevice::WriteOnly);  
  60.             fout.setVersion(QDataStream::Qt_4_5);  
  61.             fout<<quint64(0)<<quint16(0x0002)<<file1<<file2;  
  62.             fout.device()->seek(0);  
  63.             fout<<quint64(fblock.size()-sizeof(quint64));  
  64.             clientSocket->write(fblock);  
  65.             qDebug()<<"CR_MRP_Update:size:"<<QString::number(fblock.size()-sizeof(quint64));  
  66.         }  
  67.         nextBlockSize=0;  
  68.     }  
  69. }  
  70. /** 
  71.  * 释放网络连接资源 
  72.  */  
  73. void ConnectThread::threadOver()  
  74. {  
  75.     qDebug()<<"CR_MRP_Update:a client connection closed.../n";  
  76.     clientSocket->deleteLater();  
  77.     this->deleteLater();  
  78. }  

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值