Qt TCP文件传输问题

文件传输接收不了,求大佬们指教,Qt新手,

 

//clientwidget.cpp段

#include "clientwidget.h"
#include "ui_clientwidget.h"
#include<QDebug>
#include<QMessageBox>
#include<QHostAddress>
ClientWidget::ClientWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::ClientWidget)
{
    ui->setupUi(this);
    tcpsocket=new QTcpSocket(this);

    isStart=true;

    //进度条当前值
    ui->progressBar->setValue(0);
    setWindowTitle("客户端");



    connect(tcpsocket,&QTcpSocket::readyRead,
            [=]()
    {
    //取出接受的内容
        QByteArray buf=tcpsocket->readAll();

        if(isStart==true)
        {
            //接收头
            isStart=false;
            //解析头部信息 QString buf="hello##1024"
            //QString str="hello##1024##mike;
            // str.section("##",0,0);

            //初始化
            fileName=QString(buf).section("##",0,0);
            filesize=QString(buf).section("##",1,1).toInt();
            recvsize=0;

            //设置进度条
            ui->progressBar->setMinimum(0);
            ui->progressBar->setMaximum(filesize/1024);
            ui->progressBar->setValue(0);

            //打开文件
            file.setFileName(fileName);
            //只写的方式打开文件

            bool isOk=file.open(QIODevice::WriteOnly);
            if(false==isOk)
            {
                qDebug()<<"WriteOnly error";
                tcpsocket->disconnectFromHost();//断开连接
                tcpsocket->close();

                return;//如果打开失败,中断函数
            }

            //弹出对话框,显示接收文件的信息
            QString str=QString("接收的文件:[%1:%2kb]").arg(fileName).arg(filesize/1024);
            QMessageBox::information(this,"文件信息",str);


        }
        else//文件信息
            {
            qint64 len=file.write(buf);
            if(len>0)//接收数据大于0
            {
                recvsize+=len;//累计接收大小
                qDebug()<<len;
            }
            //更新进度条

            ui->progressBar->setValue(recvsize/1024);

            if(recvsize==filesize)
            {
                //先给服务器发送(文件接收完成的信息)
                tcpsocket->write("file done");

                QMessageBox::information(this,"finish","文件接收完毕");
                file.close();

                tcpsocket->disconnectFromHost();
                tcpsocket->close();

            }
        }

    }

            );
}

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





void ClientWidget::on_pushButton_clicked()
{
    //获取文件信息
    QString ip=ui->lineEditIP->text();
    qint16 port=ui->lineEditPort->text().toUInt();

    tcpsocket->connectToHost(QHostAddress(ip),port);

    isStart=true;
    ui->progressBar->setValue(0);
}



//serverwidget.cpp段
#include "serverwidget.h"
#include "ui_serverwidget.h"
#include<QFileDialog>
#include<QFileInfo>
#include<QDebug>
serverWidget::serverWidget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::serverWidget)
{
    ui->setupUi(this);

    tcpserver=new QTcpServer(this);


    //监听
    tcpserver->listen(QHostAddress::Any,8888);
    setWindowTitle("服务器端口为:8888");

    //两个按钮都不能按
    ui->buttonFile->setEnabled(false);
    ui->buttonSend->setEnabled(false);


    //如果客户端和服务器连接
    //tcpserver会自动触发newConnection

    connect(tcpserver,&QTcpServer::newConnection,
            [=]()
    {
        //取出建立好连接的套接字
        tcpsocket=tcpserver->nextPendingConnection();
        //获取对方的IP和端口
        QString ip=tcpsocket->peerAddress().toString();
        quint16 port=tcpsocket->peerPort();

        QString str=QString("[%1:%2] 成功连接").arg(ip).arg(port);

        //显示到编辑区
        ui->textEdit->setText(str);


        //连接成功后两个按钮可以按
        ui->buttonFile->setEnabled(true);

        connect(tcpsocket,&QTcpSocket::readyRead,
                [=]()
        {
        //取客户端的信息
            QByteArray buf=tcpsocket->readAll();
            if(QString(buf)=="file down")
            {
                //文件接收完毕
               ui->textEdit->append("文件发送完毕");
               file.close();

               //断开客户端
               tcpsocket->disconnectFromHost();
               tcpsocket->close();
            }

        }
                );


    }
            );
    connect(&timer,&QTimer::timeout,
            [=]()
    {
    //关掉定时器
        timer.stop();

        //发送文件
        sendData();

    }
            );



}

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

//选择文件按钮
void serverWidget::on_buttonFile_clicked()
{
    QString filepath=QFileDialog::getOpenFileName(this,"open","../");
    //如果选择文件路径有效
    if(false==filepath.isEmpty())
     {
        fileName.clear();
        filesize=0;

        //获取文件信息
        QFileInfo info(filepath);
        fileName=info.fileName();//获取文件名
        filesize=info.size();//获取文件大小

        sendsize=0;//发送文件大小

        //只读方式打开文件
        //指定文件名字
        file.setFileName(filepath);

        //打开文件
        bool isOk=file.open(QIODevice::ReadOnly);
        if(isOk==false)
        {
            qDebug()<<"只读方式打开错误";

        }

        //提示打开文件路径
        ui->textEdit->append(filepath);



        ui->buttonFile->setEnabled(false);
        ui->buttonSend->setEnabled(true);

    }
    else
        {
        qDebug()<<"选择文件路径出错";
    }

}


void serverWidget::on_buttonSend_clicked()
{
    //先发送头文件信息  文件名##文件大小
    QString head=QString("%1##%2").arg(fileName).arg(filesize);
    //发送头部信息
    qint64 len=tcpsocket->write(head.toUtf8());
    if(len>0)//头部信息发送成功
        {
        //发送真正的文件信息
        //防止TCP黏包文件
        //需要通过定时器延时 20ms
        timer.start(20);
    }
    else
        {
        qDebug()<<"头部信息发送失败";
        file.close();
        ui->buttonFile->setEnabled(true);
        ui->buttonSend->setEnabled(false);
    }
}

void serverWidget::sendData()
{
    ui->textEdit->append("正在发送文件...");
    qint64 len=0;
    do
    {
        //每次发送数据的大小
        char buf[4*1024]={0};
        len=0;

        //往文件中读数据
        len=file.read(buf,sizeof(buf));
        //发送数据,读多少,发多少
        len=tcpsocket->write(buf,len);

        //发送的数据累计
        sendsize+=len;

    }while(len>0);

    //是否发送完毕
    if(sendsize==filesize)
    {
        ui->textEdit->append("文件发送完毕");

        file.close();

        //把客户端关掉
        tcpsocket->disconnectFromHost();
        tcpsocket->close();
    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值