当前位置:   article > 正文

Qt网络编程小项目-基于Tcp协议的文件传输项目_qt中网络编程怎样发送与接收文件

qt中网络编程怎样发送与接收文件

目录

项目描述

Qt下Tcp服务器端和客户端流程:

具体流程:

客户端:

服务器端:

源码:

服务器端:

服务器头文件:

服务器源文件:

服务器端ui

客户端:

客户端头文件:

客户端源文件:

客户端ui:


项目描述

利用Tcp协议实现服务器端和客户端数据的传输,客户端向服务器端传输文件(音频、视频、文本)类似客户端上传文件

Qt下Tcp服务器端和客户端流程:

具体流程:

客户端:

头文件:

#include <QWidget>

#include <QTcpSocket>

#include <QFileDialog>//显示文件对话框

#include <QFileInfo>//获取文件信息

#include <QTimer>


  1. 客户端连接服务器

客户端只需一个接收套接字 tcpSocket = new QTcpSocket(this);

tcpSocket->connectToHost(Ip,port);连接到服务器端

开辟一个QByteArray array内存空间,通过信号与槽connect

  1. 1选择要传输的文件

QString filePath = QFileDialong::getOpenFileName(this);

QFileInfo FileData(filePath);//获取文件信息

filename = FileData.fileName();//获得文件名字

filesize = FileData.size();//获得文件大小 字节

  1.  2文件操作

QFile file创建一个文件描述符,

  1. 3文件发送

文件的发送分为两个部分:

        a.先发送一个包含文件信息的字符串类型为" filename**filesize "

QString head = filename + "**" + QString::number(filename); 
qint64 length = tcpSocket->write(head.toutf8); 
if(length>0)//发送成功 
        myTimer->start(20);//设置一个定时器 防止内容粘包 
else //发送不成功 
        file.close();

        b.防止粘包发送成功后设置一个延迟 设置一个定时器myTimer 开始发送文件本身

 myTimer = new QTimer(this); 
connect(myTimer,&QTimer::timeout, this ,[&](){ 
myTimer->stop(); 
qint64 len; 
qint64 sendSize = 0;//已经发送文件大小 
do{ char buf[4*1024] = {0};//一次读取char这么大 
len = 0; 
len = file.read(buf,sizeof(buf));//从file中读取4096放到buf中 
tcpSocket->write(buf,len);//写入 
sendSize += len; ui->progressBar->setValue(sendSize/1024);//设置进度条 }while(len>0); 
if(sendSize == filesize)//发送内存大小和实际文件内存大小相等传输完毕 
{ file.close(); 
tcpSocket->disconnectFromHost();//断开连接 
tcpSocket->close();
 } });

服务器端:

头文件:

#include <QTcpServer>监听套接字

#include <QTcpSocket>通信套接字

QTcpServer *tcpserver;监听套接字对象

QTcpSocket *clientConnection = nullptr;通信套接字对象

        1. 监听对象开辟空间

tcpserver = new QTcpServer(this);

调用listen()监听 这里使用的是本地主机127.0.0.1的Ip地址

tcpserver ->listen(QHostAddress::LocalHost,ui->lineEdit->text().toInt());

        2.连接客户端 接受文件

  • 采用信号与槽的方式

connect(tcpserver,&QTcpServer::newConnection,this,[&](){
        clientConnection = tcpserver->nextPendingConnection();
        clientConnection->write("Welcome to connect to the server!");//连接成功向客户端发送成功连接字样

        //接收端
        connect(clientConnection, QTcpSocket::readyRead,this,[&](){
            QByteArray array = clientConnection->readAll();
            if(headInfo){ //第一次读出的信息应该是head文件信息
                 headInfo = false;
                 recvSize = 0;
                 filename = QString(array).section("**",0,0); //分割出需要的信息
                 filesize = QString(array).section("**",1,1).toInt();

                 file.setFileName(filename);
                 file.open(QIODevice::WriteOnly);//发送端只读打开

                 //设置进度条
                 ui->progressBar->setMinimum(0);
                 ui->progressBar->setMaximum(filesize/1024);
                 ui->progressBar->setValue(0);//初始为0
            }
            else{//这里收到的文件是文件本身
                qint64 length = file.write(array);
                if(length >0)
                    recvSize += length;
                 ui->progressBar->setValue(recvSize/1024);
                 if(recvSize == filesize)
                 {
                     //文件接受完毕
                     QMessageBox::information(this,"完成","文件接受完成");
                     file.close();
                 }
            }
        });
    } );

源码:

服务器端:

服务器头文件:

  1. #ifndef WIDGET_H
  2. #define WIDGET_H
  3. #include <QWidget>
  4. #include <QTcpServer>
  5. #include <QTcpSocket>
  6. #include <QFileDialog>
  7. #include <QFile>
  8. #include <QMessageBox>
  9. namespace Ui {
  10. class Widget;
  11. }
  12. class Widget : public QWidget
  13. {
  14. Q_OBJECT
  15. public:
  16. explicit Widget(QWidget *parent = 0);
  17. ~Widget();
  18. private slots:
  19. void on_pushButton_clicked();
  20. private:
  21. Ui::Widget *ui;
  22. QTcpServer *tcpserver;//监听服务器端套接字
  23. QTcpSocket *clientConnection = nullptr;//通信套接字
  24. bool headInfo = true;
  25. QString filename;
  26. qint64 filesize;
  27. qint64 recvSize;//收到文件的大小
  28. QFile file;
  29. };
  30. #endif // WIDGET_H

服务器源文件:

  1. #include "widget.h"
  2. #include "ui_widget.h"
  3. #include <QDebug>
  4. Widget::Widget(QWidget *parent) :
  5. QWidget(parent),
  6. ui(new Ui::Widget)
  7. {
  8. ui->setupUi(this);
  9. setWindowTitle("服务器");
  10. ui->lineEdit->setText("8080");//初始端口号值
  11. tcpserver = new QTcpServer(this);
  12. }
  13. Widget::~Widget()
  14. {
  15. delete ui;
  16. }
  17. void Widget::on_pushButton_clicked()
  18. {
  19. tcpserver ->listen(QHostAddress::LocalHost,ui->lineEdit->text().toInt());//(LocalHost本机环回地址)
  20. connect(tcpserver,&QTcpServer::newConnection,this,[&](){
  21. clientConnection = tcpserver->nextPendingConnection();
  22. clientConnection->write("Welcome to connect to the server!");
  23. //接收端
  24. connect(clientConnection, QTcpSocket::readyRead,this,[&](){
  25. QByteArray array = clientConnection->readAll();
  26. if(headInfo){ //第一次读出的信息应该是head文件信息
  27. headInfo = false;
  28. recvSize = 0;
  29. filename = QString(array).section("**",0,0); //分割出需要的信息
  30. filesize = QString(array).section("**",1,1).toInt();
  31. file.setFileName(filename);
  32. file.open(QIODevice::WriteOnly);//发送端只读打开
  33. //设置进度条
  34. ui->progressBar->setMinimum(0);
  35. ui->progressBar->setMaximum(filesize/1024);
  36. ui->progressBar->setValue(0);//初始为0
  37. }
  38. else{//这里收到的文件是文件本身
  39. qint64 length = file.write(array);
  40. if(length >0)
  41. recvSize += length;
  42. ui->progressBar->setValue(recvSize/1024);
  43. if(recvSize == filesize)
  44. {
  45. //文件接受完毕
  46. QMessageBox::information(this,"完成","文件接受完成");
  47. file.close();
  48. }
  49. }
  50. });
  51. } );
  52. ui->pushButton->setEnabled(false);
  53. }

服务器端ui

客户端:

客户端头文件:

  1. #ifndef WIDGET_H
  2. #define WIDGET_H
  3. #include <QWidget>
  4. #include <QTcpServer>
  5. #include <QTcpSocket>
  6. #include <QFileDialog>//显示文件对话框
  7. #include <QFileInfo>//获取文件信息
  8. #include <QTimer>
  9. namespace Ui {
  10. class Widget;
  11. }
  12. class Widget : public QWidget
  13. {
  14. Q_OBJECT
  15. public:
  16. explicit Widget(QWidget *parent = 0);
  17. ~Widget();
  18. private slots:
  19. void on_pushButton_clicked();
  20. void on_pushButton_2_clicked();
  21. void on_pushButton_3_clicked();
  22. private:
  23. Ui::Widget *ui;
  24. QTcpSocket *tcpSocket; //客户端只需要一个接受套接字
  25. QString filename;
  26. qint64 filesize;
  27. QFile file; //文件描述符
  28. QTimer *myTimer; //定时器
  29. };
  30. #endif // WIDGET_H

客户端源文件:

  1. #include "widget.h"
  2. #include "ui_widget.h"
  3. #include <QDebug>
  4. Widget::Widget(QWidget *parent) :
  5. QWidget(parent),
  6. ui(new Ui::Widget)
  7. {
  8. ui->setupUi(this);
  9. setWindowTitle("客户端");
  10. tcpSocket = new QTcpSocket(this);
  11. connect(tcpSocket, &QTcpSocket::readyRead,this,[&](){
  12. QByteArray array = tcpSocket->readAll();
  13. qDebug()<<"服务器: "<<array;
  14. });
  15. myTimer = new QTimer(this);
  16. connect(myTimer,&QTimer::timeout, this ,[&](){
  17. myTimer->stop();
  18. qint64 len;
  19. qint64 sendSize = 0;//已经发送文件大小
  20. do{
  21. char buf[4*1024] = {0};//一次读取char这么大
  22. len = 0;
  23. len = file.read(buf,sizeof(buf));
  24. tcpSocket->write(buf,len);
  25. sendSize += len;
  26. ui->progressBar->setValue(sendSize/1024);
  27. }while(len>0);
  28. if(sendSize == filesize )
  29. {
  30. file.close();
  31. tcpSocket->disconnectFromHost();//断开连接
  32. tcpSocket->close();
  33. }
  34. });
  35. }
  36. Widget::~Widget()
  37. {
  38. delete ui;
  39. }
  40. void Widget::on_pushButton_clicked()//连接按钮
  41. {
  42. //连接服务器
  43. tcpSocket->connectToHost(ui->lineEdit->text(),ui->lineEdit_2->text().toInt());
  44. }
  45. void Widget::on_pushButton_2_clicked()//打开按钮
  46. {
  47. QString filePath = QFileDialog::getOpenFileName(this);
  48. //发送文件时先发送一个文件名字和文件大小,如果两端文件大小相同说明发送完毕
  49. QFileInfo FileData(filePath);//获取文件信息
  50. filename = FileData.fileName();//获得文件名字
  51. filesize = FileData.size();//获得文件大小
  52. qDebug()<<"文件名:"<<filename;
  53. qDebug()<<"文件大小:"<<filesize;
  54. if(!filePath.isEmpty())
  55. {
  56. ui->label_3->setText(filePath);//显示文件名字
  57. file.setFileName(filePath);
  58. file.open(QIODevice::ReadOnly);//发送端只读打开
  59. }
  60. //设置进度条
  61. ui->progressBar->setMinimum(0);
  62. ui->progressBar->setMaximum(filesize/1024);
  63. ui->progressBar->setValue(0);//初始为0
  64. }
  65. void Widget::on_pushButton_3_clicked()
  66. {
  67. //头信息
  68. QString head = filename + "**" + QString::number(filesize); //强制类型转换成字符串
  69. //发送head文件
  70. qint64 length = tcpSocket->write(head.toUtf8());
  71. if(length>0)//发送成功
  72. myTimer->start(20);//设置一个定时器 防止内容粘包
  73. else //发送不成功
  74. file.close();
  75. }

客户端ui:

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

闽ICP备14008679号