qt/c++学习笔记之基于tcp的文件同步程序demo(第二部分)

server 服务器端
头文件
filebase.h

#ifndef FILEBASE_H
#define FILEBASE_H

#include 
#include 
#include 
#include 
#include
enum MsgType{

    MsgTypeInvaid =0,
MsgTypeFile,
    MsgTypeDel,
    MsgTypeRename

};
class filebase : public QObject
{
    Q_OBJECT
public:
    explicit filebase(QObject *parent = nullptr);

public slots:

    void onReadReady();


    void onNewConnection();

    void onConnected();

    void onDisconnected();
    void onError(QAbstractSocket::SocketError scoketerro);

signals:
void doFile(const QString &filename,const QByteArray &data);
void doDel(const QString &filename);
void doRename(const QString &fileold,const QString &filenew);

private:
    QTcpServer server;
    QList<QTcpSocket *> client;
    int imageindex;
     quint32 sizepacklast;
};

#endif // FILEBASE_H

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include 
#include "filebase.h"
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
private slots:
    void onFile(const QString &filename,const QByteArray &data);
    void onDel(const QString &filename);
    void onRename(const QString &fileold,const QString &filenew);

private:
    Ui::Widget *ui;
    filebase filebb;
    QString fileServerpath;
};
#endif // WIDGET_H

filebase.cpp

#include "filebase.h"

filebase::filebase(QObject *parent) : QObject(parent)
{

    imageindex=0;
    sizepacklast=0;
        connect(&server,SIGNAL(newConnection()),this,SLOT(onNewConnection()));

        bool ok =server.listen(QHostAddress::AnyIPv4,8888);
        qDebug()<<"listen"<<ok;
}

void filebase::onReadReady()
{
    QObject *obj=this->sender();
    QTcpSocket *socket =qobject_cast<QTcpSocket *>(obj);
    //粘包,半包问题处理
qint64 sizeNow=0;
   do{
    //当前缓冲区大小
   sizeNow =socket->bytesAvailable();
       QDataStream stream(socket);
         if(sizepacklast==0){
            if(sizeNow<sizeof(quint32))
            {

                return;
            }

            stream>>sizepacklast;//已经有值
        }

    //包完整判断
    if(sizeNow<sizepacklast-4)
    {
     return;
   }

    int msgType =MsgTypeInvaid;

    stream >>msgType;



    //判断剩下的字节数,是否会有粘包
    sizeNow =socket->bytesAvailable();
  sizepacklast=0;
qDebug()<<msgType;

  switch (msgType) {

  case MsgTypeFile:
  {
      QByteArray dataFileContent;
      QString filename;
qDebug()<<"doFile";
      stream>>filename>>dataFileContent;
qDebug()<<filename;
qDebug()<<dataFileContent;
      emit doFile(filename,dataFileContent);
      break;
  }
  case MsgTypeDel:
  {
      QString fileDel;
      stream>>fileDel;
      qDebug()<<"doDel";
       emit doDel(fileDel);
      break;
  }
  case MsgTypeRename:
  {
      QString fileold;
      QString filenew;
        qDebug()<<"doRename";
      stream>>fileold>>filenew;
      emit doRename(fileold,filenew);
  break;
  }

  }

   }while(sizeNow>0);

}

void filebase::onNewConnection()
{
    //socket 和客户端进行通信
    QTcpSocket * socket =server.nextPendingConnection();

    client.append(socket);



       connect(socket,SIGNAL(readyRead()),this,SLOT(onReadReady()));
    connect(socket,SIGNAL(connected()),this,SLOT(onConnected()));
     connect(socket,SIGNAL(disconnected()),this,SLOT(onDisconnected()));
      connect(socket,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(onError(QAbstractSocket::SocketError)));

}

void filebase::onConnected()
{
qDebug()<<"conntion";
}

void filebase::onDisconnected()
{
    QObject *obj=this->sender();
    QTcpSocket *socket =qobject_cast<QTcpSocket *>(obj);
    client.removeAll(socket);
socket->close();
 qDebug()<<"onDisconnected";
}

void filebase::onError(QAbstractSocket::SocketError scoketerro)
{
   qDebug()<<"onError";
}

widget.h

#include "widget.h"
#include "ui_widget.h"
#include 
#include
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    connect(&filebb,SIGNAL(doFile(QString,QByteArray)),this,SLOT(onFile(QString,QByteArray)));
    connect(&filebb,SIGNAL(doDel(QString)),this,SLOT(onDel(QString)));
    connect(&filebb,SIGNAL(doRename(QString,QString)),this,SLOT(onRename(QString,QString)));
    fileServerpath="C:/Users/f/Desktop/server";

}

Widget::~Widget()
{
    delete ui;
}

void Widget::onFile(const QString &filename, const QByteArray &data)
{
qDebug()<<"file"<<filename;
//filename是客户端的路径

QFileInfo fileinfoo(filename);

QString fileNameJust =fileinfoo.fileName();
QString fileNameLocal =fileServerpath +"/"+fileNameJust;
QFile file(fileNameLocal);
if(!file.open(QIODevice::WriteOnly))
{

    qDebug()<<"open faild";
}
file.write(data);
file.close();
}

void Widget::onDel(const QString &filename)
{
qDebug()<<"del"<<filename;

QFileInfo fileinfoo(filename);

QString fileNameJust =fileinfoo.fileName();
QString fileNameLocal =fileServerpath +"/"+fileNameJust;

QFile::remove(fileNameLocal);
}

void Widget::onRename(const QString &fileold, const QString &filenew)
{
qDebug()<<"rename"<<fileold<<"new name"<<filenew;
QFileInfo fileinfoold(fileold);

QString fileNameJustold =fileinfoold.fileName();
QString fileNameLocalold =fileServerpath +"/"+fileNameJustold;


QFileInfo fileinfonew(filenew);

QString fileNameJustnew=fileinfonew.fileName();
QString fileNameLocalnew =fileServerpath +"/"+fileNameJustnew;

QFile::rename(fileNameLocalold,fileNameLocalnew);
}


main.cpp

#include "widget.h"

#include 

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();
}

qt/c++学习笔记之基于tcp的文件同步程序demo(第二部分)_第1张图片

你可能感兴趣的:(qt,c++,学习)