当前位置:   article > 正文

Qt-socket网络 - tcp文件传输_qtcpsocket发送文件流

qtcpsocket发送文件流

服务端

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QTcpServer>
#include <QTcpSocket>
#include <QHostAddress>
#include <QHostInfo>
#include <QFileDialog>
#include <QFile>
#include <QDebug>
#include <QString>
#include <QDataStream>
#include <QTimer>

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 on_pushButton_clicked();

    void on_pushButton_3_clicked();

    void myGetNewRead();

    void on_pushButton_2_clicked();

    void dataReadySend();

private:
    Ui::Widget *ui;
    QTcpSocket *clientSock;
    QHostAddress servAddress;
    quint16 servPort;
    QString info;
    QFile file;
    QFileInfo fileInfo;
    QTimer *myTimer;
};
#endif // WIDGET_H

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QProgressBar>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    setWindowTitle("client");
    this->resize(720,570);

    ui->lineEdit->setText("127.0.0.1");
    ui->lineEdit_2->setText("8080");

    ui->pushButton_2->setEnabled(false);
    ui->pushButton_3->setEnabled(false);
    ui->progressBar->setValue(0);

    clientSock=new QTcpSocket(this);
    servAddress=QHostAddress(ui->lineEdit->text());
    servPort=ui->lineEdit_2->text().toUInt();

    connect(clientSock,&QTcpSocket::readyRead,this,&Widget::myGetNewRead);

    info=QString("%1:%2").arg(ui->lineEdit->text(),ui->lineEdit_2->text());

     // 防止粘包 设置定时器延时发送
    myTimer=new QTimer(this);
    connect(myTimer,&QTimer::timeout,this,&Widget::dataReadySend);
}

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


void Widget::on_pushButton_clicked()
{
    clientSock->connectToHost(servAddress,servPort);
    if (!clientSock->waitForConnected(10000))
    {
        ui->textEdit->append("ERROR: connect failed...");
        return;
    }

    ui->textEdit->append("connect server "+info);

    ui->pushButton->setEnabled(false);
    ui->pushButton_3->setEnabled(true);
}


void Widget::on_pushButton_3_clicked()
{
    QString fileName=QFileDialog::getOpenFileName(this,"打开文件","./");

    fileInfo=QFileInfo(fileName);
    ui->lineEdit_3->setText(fileInfo.absoluteFilePath());

    file.setFileName(fileInfo.absoluteFilePath());
    if (!file.open(QIODevice::ReadOnly))
    {
        ui->textEdit->append("ERROR: file open failed...");
        return ;
    }

    ui->textEdit->append("ready to send file info:");
    ui->textEdit->append("file name: "+fileInfo.fileName());
    ui->textEdit->append("file size: "+QString::number(fileInfo.size())+" bytes");

    ui->progressBar->setMinimum(0);
    ui->progressBar->setMaximum(fileInfo.size()/1024);


    ui->pushButton_3->setEnabled(false);
    ui->pushButton_2->setEnabled(true);
}

void Widget::myGetNewRead()
{
    QByteArray readArray=clientSock->readAll();
    if (!readArray.isEmpty())
    {
        ui->textEdit->append(QString("receive from server %1:").arg(info));
        ui->textEdit->append(readArray);
    }

    if (QString(readArray)=="done")
    {
        ui->textEdit->append("server receive done...");
        ui->textEdit->append("close client...");
        clientSock->disconnectFromHost();
    }

}

void Widget::on_pushButton_2_clicked()
{
    // version 1
    // 分隔符传入
    QString dataHead=fileInfo.fileName()+"**"+QString::number(fileInfo.size());
    qint64 dataHeadWrittenbytes=clientSock->write(dataHead.toUtf8());

    // version 2
//    QByteArray dataHead;
//    QDataStream dataHeadStream(&dataHead,QIODevice::WriteOnly);
//    dataHeadStream<<fileInfo.fileName()<<fileInfo.size();
//    qint64 dataWrittenbytes=clientSock->write(dataHead);

    if (dataHeadWrittenbytes<=0)
    {
        ui->textEdit->append("ERROR: file data written failed");
        file.close();
        return ;
    }

    // 为了防止数据粘包 用定时器延时发送
    myTimer->start(3000);

    // version 2
    // 将文件绑定到数据流上
//    QByteArray dataArray;
//    dataArray.resize(fileInfo.size());
//    QDataStream dataStream(&dataArray,QIODevice::WriteOnly);

//    dataStream<<file.readAll();
}

void Widget::dataReadySend()
{
    myTimer->stop(); // 关闭定时器

    QByteArray dataArray;
    dataArray.resize(1024);

    qint64 dataSize=1;
    qint64 dataWrittenBytes=0;
    while (dataSize>0)
    {
        // 实际读取的大小
        dataSize=file.read(dataArray.data(),dataArray.size());
        // 发送实际的大小
        dataWrittenBytes+=clientSock->write(dataArray.data(),dataSize);

        // 设置进度条
        ui->progressBar->setValue(dataWrittenBytes/1024);
    }

    if (dataWrittenBytes==fileInfo.size())
    {
        file.close();
        ui->textEdit->append("client send data done...");

        // 断开连接
//        clientSock->disconnectFromHost();
    }

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162

.ui

在这里插入图片描述

客户端

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QTcpServer>
#include <QTcpSocket>
#include <QHostAddress>
#include <QString>
#include <QFile>
#include <QFileInfo>

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 on_pushButton_clicked();
    void myGetNewConnect();
    void myGetNewRead();

private:
    Ui::Widget *ui;
    QTcpServer *servSock;
    QTcpSocket *listenSock;
    QHostAddress servAddress;
    quint64 servPort;
    QString servSockInfo;
    QString clientSockInfo;

    bool isHead;
    QString fileName;
    qint64 fileSize;
    qint64 dataReadBytes;
    qint64 dataHeadReadBytes;

    QFile file;

};
#endif // WIDGET_H

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48

widget.cpp

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    ui->lineEdit->setText("127.0.0.1");
    ui->lineEdit_2->setText("8080");

    ui->progressBar->setMinimum(0);
    ui->progressBar->setMaximum(1024);
    ui->progressBar->setValue(0);

    servSockInfo=QString("%1:%2").arg(ui->lineEdit->text(),ui->lineEdit_2->text());

    servSock=new QTcpServer(this);
    listenSock=new QTcpSocket(this);

    servAddress=QHostAddress(ui->lineEdit->text());
    servPort=ui->lineEdit_2->text().toUInt();

    isHead=true;
    dataHeadReadBytes=0;
    dataReadBytes=0;
}

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


void Widget::on_pushButton_clicked()
{

    servSock->listen(servAddress,servPort);
    connect(servSock,&QTcpServer::newConnection,this,&Widget::myGetNewConnect);
    ui->textEdit->append("server listening... waiting a connect...");
}


void Widget::myGetNewConnect()
{
    listenSock=servSock->nextPendingConnection();
    if (listenSock->isValid() && listenSock->isOpen())
    {
        ui->lineEdit_3->setText(listenSock->peerAddress().toString());
        ui->lineEdit_4->setText(QString::number(listenSock->peerPort()));

        clientSockInfo=QString("%1:%2").arg(ui->lineEdit_3->text(),ui->lineEdit_4->text());

        ui->textEdit->append(QString("receive a new connect request: [ %1 -> %2 ]").arg(servSockInfo,clientSockInfo));

        connect(listenSock,&QTcpSocket::readyRead,this,&Widget::myGetNewRead);

        listenSock->write("connect server success");

    }
}

void Widget::myGetNewRead()
{
//    QByteArray
    if (isHead) // 判断是否是数据头
    {
        isHead=false;

        // 这里处理粘包的机制是通过延时的方式 不建议这么写
        // head format:
        QByteArray dataHeadArray=listenSock->readAll();
        fileName=QString(dataHeadArray).section("**",0,0);
        fileSize=QString(dataHeadArray).section("**",1,1).toInt();

        // 创建文件
        file.setFileName(fileName);
        file.open(QIODevice::WriteOnly);

        ui->textEdit->append("receive file: info:");
        ui->textEdit->append("fileName: "+fileName+" bytes: "+QString::number(fileSize));
        ui->textEdit->append("create a file ing...");

        ui->progressBar->setMaximum(fileSize/1024);
    }
    else
    {
        qint64 dataSize=0;
        QByteArray dataArray=listenSock->readAll();
        if (!dataArray.isEmpty())
        {
            dataSize=file.write(dataArray);
            if (dataSize>0)
            {
                dataReadBytes+=dataSize;
                ui->progressBar->setValue(dataReadBytes/1024);
            }
            if (dataReadBytes==fileSize)
            {
                ui->textEdit->append("receive data done...");
                file.close();

                listenSock->write("done");
            }
        }
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109

.ui

在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/487930
推荐阅读
相关标签
  

闽ICP备14008679号