Qt QtcpSocket 发送文件(包括数据块总大小)

来源:互联网 发布:vr效果图 制作软件 编辑:程序博客网 时间:2024/05/01 08:10

客户端

mainwindow.h

#ifndef MAINWINDOW_H#define MAINWINDOW_H#include <QMainWindow>#include<QByteArray>#include<QDataStream>#include<QString>#include<QTcpServer>#include<QFile>#include<QUrl>#include<QHostAddress>#include<QTcpSocket>namespace Ui {class MainWindow;}class MainWindow : public QMainWindow{    Q_OBJECTprivate:    qint64 m_bytestotal;    qint64 m_bytesreceived;    QTcpSocket * m_socket;public:    explicit MainWindow(QWidget *parent = 0);    ~MainWindow();private slots:    void connected();private:    Ui::MainWindow *ui;};#endif // MAINWINDOW_H
mainwindow.cpp

#include "mainwindow.h"#include "ui_mainwindow.h"#include<QMessageBox>MainWindow::MainWindow(QWidget *parent) :    QMainWindow(parent),    ui(new Ui::MainWindow){    ui->setupUi(this);    this->m_socket=new QTcpSocket(this);    this->m_socket->connectToHost(QHostAddress::LocalHost,520);    connect(this->m_socket,SIGNAL(connected()),this,SLOT(connected()));}MainWindow::~MainWindow(){    delete ui;}void MainWindow::connected(){    /*********打开文件*********/    QFile f("F://Dokcer实践.pdf");    f.open(QIODevice::ReadOnly);    /******二进制数据块******/    QByteArray block;    /******读取文件**********/    QByteArray data=f.readAll();    /*********设置数据流***********/    QDataStream dts(&block,QIODevice::WriteOnly);    /*****先格式化数据块*********/    dts<<qint64(0)<<qint64(0)<<QString("xx.pdf");    /*******指向头部*************/    dts.device()->seek(0);    /*******计算数据总大小*********/    dts<<(qint64)(block.size()+f.size());    QMessageBox::about(this,"x",QString::number((qint64)(block.size()+f.size())));    /**********文件名大小(所占空间)***************/    dts<<(qint64)(block.size()-sizeof(qint64)*2);     QMessageBox::about(this,"x",QString::number((qint64)(block.size()-sizeof(qint64)*2)));     /********再次占位**********/    dts<<QString("xx.pdf");    /*********写入文件数据***********/    dts<<data;    QMessageBox::about(this,"x",QString::number(block.size()));    /*******发送*********/    this->m_socket->write(block);}
main.cpp

#include "mainwindow.h"#include <QApplication>int main(int argc, char *argv[]){    QApplication a(argc, argv);    MainWindow w;    w.show();    return a.exec();}





服务器端

mainwindow.h

#ifndef MAINWINDOW_H#define MAINWINDOW_H#include <QMainWindow>#include<QByteArray>#include<QDataStream>#include<QString>#include<QTcpServer>#include<QFile>#include<QUrl>#include<QHostAddress>#include<QTcpSocket>namespace Ui {class MainWindow;}class MainWindow : public QMainWindow{    Q_OBJECTprivate:    QTcpServer * m_server;    QTcpSocket * m_socket;    qint64 m_bytesreceived;    qint64 m_bytesfilenamesize;    qint64 m_bytestotal;    QString m_filename;    QFile * m_file;public:    explicit MainWindow(QWidget *parent = 0);    ~MainWindow();private slots:    void on_connected();    void on_disconnected();    void on_readyread();    void on_btn_discon_clicked();    void on_btn_opendir_clicked();private:    Ui::MainWindow *ui;};#endif // MAINWINDOW_H
mainwindow.cpp

#include "mainwindow.h"#include "ui_mainwindow.h"#include<QDesktopServices>#include<QMessageBox>MainWindow::MainWindow(QWidget *parent) :    QMainWindow(parent),    ui(new Ui::MainWindow){    ui->setupUi(this);    this->m_server=new QTcpServer(this);    this->m_socket=0;    this->ui->btn_discon->hide();    this->m_bytesfilenamesize=0;    this->m_bytesreceived=0;    this->m_bytestotal=0;    this->m_file=0;    this->m_server->listen(QHostAddress::Any,520);    connect(this->m_server,SIGNAL(newConnection()),this,SLOT(on_connected()));}MainWindow::~MainWindow(){    delete ui;}void MainWindow::on_connected(){    this->m_socket=this->m_server->nextPendingConnection();    this->ui->btn_discon->show();    connect(this->m_socket,SIGNAL(disconnected()),this,SLOT(on_connected()));    connect(this->m_socket,SIGNAL(readyRead()),this,SLOT(on_readyread()));}void MainWindow::on_disconnected(){    this->ui->btn_discon->hide();    this->m_socket=0;}void MainWindow::on_readyread(){    /*******       qint64  qint64 QString QByteArray       发送网络数据 如果比较小 或者网络好 就响应一次readyread就可以了,       比较大 就会 响应很多次  这里需要if  判断好!    *****/    QDataStream in(this->m_socket);    if(this->m_bytesreceived==0){        //|还没有接收任何数据        //|如果已经发送了总大小空间数据 和文件名大小        if(this->m_socket->bytesAvailable()>=sizeof(qint64)*2)        {               QMessageBox::about(this,"x","头数据接收完成");            in>>this->m_bytestotal;            in>>this->m_bytesfilenamesize;            this->m_bytesreceived+=sizeof(qint64)*2;            /*****如果一次性全部接收完了*********/               QMessageBox::about(this,"x",QString::number(this->m_bytestotal));                QMessageBox::about(this,"x",QString::number(this->m_bytesfilenamesize));          QMessageBox::about(this,"x",QString::number(this->m_socket->bytesAvailable()));          //|如果一次就把数据接收完了                if(this->m_socket->bytesAvailable()+this->m_bytesreceived>=this->m_bytestotal)            {                   QMessageBox::about(this,"x","接收完成");                //|如果数据全部接收完毕                in>>this->m_filename;                QByteArray block;               in>>block;              //  QByteArray block=this->m_socket->readAll();                this->m_file=new QFile("E://"+this->m_filename);                this->m_file->open(QIODevice::WriteOnly);                  QMessageBox::about(this,"x",this->m_filename);                this->m_file->write(block);                  this->m_file->close();            }        }    }else{        /*******这里是2+次接收!*********/        /*******文件名和文件数据一起接收***********/        if(this->m_socket->bytesAvailable()+this->m_bytesreceived>=this->m_bytestotal)        {          QMessageBox::about(this,"x","接收完成");            //|如果数据全部接收完毕            in>>this->m_filename;           QByteArray block;            in>>block;           //  QByteArray block=this->m_socket->readAll();            this->m_file=new QFile("E://"+this->m_filename);            this->m_file->open(QIODevice::WriteOnly);            QMessageBox::about(this,"x",this->m_filename);            this->m_file->write(block);              this->m_file->close();        }    }}void MainWindow::on_btn_discon_clicked(){    this->m_socket->close();}void MainWindow::on_btn_opendir_clicked(){    QDesktopServices::openUrl(QUrl("E://"));}

main.cpp

#include "mainwindow.h"#include <QApplication>int main(int argc, char *argv[]){    QApplication a(argc, argv);    MainWindow w;    w.show();    return a.exec();}




0 0
原创粉丝点击