服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C/C++ - 基于QT制作一个简易的传输文件小工具

基于QT制作一个简易的传输文件小工具

2022-07-19 10:13一个眉头紧锁的码农 C/C++

本文主要介绍了通过QT实现的一个文件传输小工具。功能就是能实现文件的双向传输,即客户端能传给服务端,服务端可以传给客户端。文中示例代码具有一定的学习价值,感兴趣的小伙伴可以了解一下

最近因为一个事情很恼火,因为办公需要用到企业微信,但是企业微信只能在一个电脑上登陆,所以当别人发文件给你的时候,你只能一个电脑接收,创建共享文件夹也很麻烦,每次都需要去访问,很麻烦。所以准备自己写一个文件传输小工具。

功能就是能实现文件的双向传输,即客户端能传给服务端,服务端可以传给客户端。

使用的tcp通信,其实就是发消息,但是组合数据我是借鉴了IT1995大神写的代码。

先看下效果图

基于QT制作一个简易的传输文件小工具

可以看到既可以接受文件也可进行发送文件,只要2台电脑在统一局域网内,就可发送和接受数据。

基于QT制作一个简易的传输文件小工具

本地文件下出现了一份传输的文件。

直接看代码

.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QPushButton>
#include <QLineEdit>
#include <QTcpSocket>
#include <QTcpServer>
#include <QFile>
#include <QTextEdit>
#include <QProgressBar>

class Widget : public QWidget
{
  Q_OBJECT

public:
  Widget(QWidget *parent = nullptr);
  ~Widget();

  void Init();

private slots:
  void onTcpConnected();
  void onConnectClicked();
  void ServerNewConnect();
  void SocketReadData();
  void onOpenFileClicked();
  void onSendClicked();
  void updateClientProgress(qint64 numBytes);

private:
  QPushButton *m_pConnectBtn=nullptr;
  QLineEdit *m_pIpAddressEdit=nullptr;
  QLineEdit *m_pPortEdit=nullptr;
  QWidget *m_pTitleWgt=nullptr;

  QLineEdit *m_pFilePathEdit=nullptr;
  QPushButton *m_pOpenFileBtn=nullptr;
  QPushButton *m_pSendBtn=nullptr;

  QTextEdit *m_pTextEdit=nullptr;

  QProgressBar *m_pReceiverBar=nullptr;
  QProgressBar *m_pSendBar=nullptr;


  QTcpSocket *m_pTcpSocket=nullptr;
  QTcpServer *m_pTcpServer=nullptr;
  QTcpSocket *m_pTcpServerSocket=nullptr;
  //------receiver
  qint64 m_bytesReceived;
  qint64 m_fileNameSize;
  qint64 m_totalBytes;
  QString m_fileName;
  QFile *m_localFile;
  QByteArray m_inBlock;

  //send
  QFile *m_ClientlocalFile;
  QString m_ClientfileName;
  qint64 m_ClienttotalBytes;
  qint64 m_ClientbytesWritten=0;
  qint64 m_ClientbytesToWrite;
  qint64 m_ClinetpayloadSize;
  QByteArray m_ClientoutBlock;
};
#endif // WIDGET_H

.cpp

#include "widget.h"
#include <QHBoxLayout>
#include <QLabel>
#include <QValidator>
#include <QMessageBox>
#include <QFileDialog>

Widget::Widget(QWidget *parent)
  : QWidget(parent)
{
  this->resize(800,600);
  Init();
  m_pTcpSocket=new QTcpSocket(this);
  connect(m_pTcpSocket,&QTcpSocket::connected,this,&Widget::onTcpConnected);  //若连接成功,则触发此信号
  connect(m_pTcpSocket,SIGNAL(bytesWritten(qint64)),this,SLOT(updateClientProgress(qint64))); //发送数据

  m_pTcpServer=new QTcpServer(this);
  m_totalBytes=0;
  m_bytesReceived=0;
  m_fileNameSize=0;
  connect(m_pTcpServer,&QTcpServer::newConnection,this,&Widget::ServerNewConnect);
   if(!m_pTcpServer->listen(QHostAddress::Any, 2021))   //端口为2021
   {
       QMessageBox::warning(this,"Warning",m_pTcpServer->errorString(),QMessageBox::Ok);
       return;
   }
}

Widget::~Widget()
{
}

void Widget::Init()
{
  m_pConnectBtn=new QPushButton(tr("Connect"),this);
  m_pIpAddressEdit=new QLineEdit(this);
  m_pPortEdit=new QLineEdit(this);
  m_pPortEdit->setValidator(new QIntValidator());
  m_pTitleWgt=new QWidget(this);
  m_pIpAddressEdit->setFixedWidth(200);
  m_pPortEdit->setFixedWidth(200);
  m_pConnectBtn->setFixedSize(100,25);
  QLabel *ipLabel=new QLabel(tr("IpAddress:"),this);
  QLabel *portLabel=new QLabel(tr("Port:"),this);
  ipLabel->setFixedWidth(60);
  portLabel->setFixedWidth(40);
  QHBoxLayout *titleLayout=new QHBoxLayout(this);
  titleLayout->addWidget(ipLabel);
  titleLayout->addWidget(m_pIpAddressEdit);
  titleLayout->addWidget(portLabel);
  titleLayout->addWidget(m_pPortEdit);
  titleLayout->addWidget(m_pConnectBtn);
  titleLayout->setMargin(5);
  titleLayout->setSpacing(10);
  titleLayout->addStretch();
  m_pTitleWgt->setFixedHeight(40);
  m_pTitleWgt->setLayout(titleLayout);

  m_pIpAddressEdit->setText("192.168.2.110");
  m_pPortEdit->setText("2021");

  m_pPortEdit->setEnabled(false);

  m_pFilePathEdit=new QLineEdit(this);
  m_pOpenFileBtn=new QPushButton(tr("Open File"),this);
  m_pSendBtn=new QPushButton(tr("Send"));

  m_pFilePathEdit->setFixedWidth(500);
  m_pOpenFileBtn->setFixedSize(100,25);
  m_pSendBtn->setFixedSize(100,25);

  m_pSendBtn->setEnabled(false);

  QWidget *bottomWgt=new QWidget(this);
  QHBoxLayout *bottomLayout=new QHBoxLayout(this);
  bottomLayout->addWidget(m_pFilePathEdit);
  bottomLayout->addWidget(m_pOpenFileBtn);
  bottomLayout->addWidget(m_pSendBtn);
  bottomLayout->setMargin(5);
  bottomLayout->setSpacing(5);
  bottomLayout->addStretch();
  bottomWgt->setLayout(bottomLayout);

  m_pTextEdit=new QTextEdit(this);

  QLabel *receiverLabel=new QLabel(tr("Receiver Speed"),this);
  QLabel *SendLabel=new QLabel(tr("Send Speed"),this);
  receiverLabel->setFixedWidth(100);
  SendLabel->setFixedWidth(100);
  m_pReceiverBar=new QProgressBar(this);
  m_pSendBar=new QProgressBar(this);
  m_pReceiverBar->setFixedSize(300,30);
  m_pSendBar->setFixedSize(300,30);
  m_pReceiverBar->setOrientation(Qt::Horizontal);
  m_pSendBar->setOrientation(Qt::Horizontal);

  QWidget *receiverBarWgt=new QWidget(this);
  QHBoxLayout *receiverBarLayout=new QHBoxLayout(this);
  receiverBarLayout->addWidget(receiverLabel);
  receiverBarLayout->addWidget(m_pReceiverBar);
  receiverBarLayout->addStretch();
  receiverBarLayout->setSpacing(5);
  receiverBarWgt->setLayout(receiverBarLayout);

  QWidget *sendBarWgt=new QWidget(this);
  QHBoxLayout *sendBarLayout=new QHBoxLayout(this);
  sendBarLayout->addWidget(SendLabel);
  sendBarLayout->addWidget(m_pSendBar);
  sendBarLayout->addStretch();
  sendBarLayout->setSpacing(5);
  sendBarWgt->setLayout(sendBarLayout);

  connect(m_pConnectBtn,&QPushButton::clicked,this,&Widget::onConnectClicked);
  connect(m_pOpenFileBtn,&QPushButton::clicked,this,&Widget::onOpenFileClicked);
  connect(m_pSendBtn,&QPushButton::clicked,this,&Widget::onSendClicked);

  QVBoxLayout *mainLayout=new QVBoxLayout(this);
  mainLayout->addWidget(m_pTitleWgt);
  mainLayout->addWidget(bottomWgt);
  mainLayout->addWidget(receiverBarWgt);
  mainLayout->addWidget(sendBarWgt);
  mainLayout->addWidget(m_pTextEdit);
  mainLayout->setMargin(0);
  mainLayout->addStretch();
  this->setLayout(mainLayout);

}

void Widget::onTcpConnected()
{
  m_pTextEdit->append("Connect Server Success!");
}

void Widget::onConnectClicked()
{
  QString strip=m_pIpAddressEdit->text();
  QString strport=m_pPortEdit->text();
  if(strip!=""&&strport!="")
  {
      m_pTcpSocket->connectToHost(strip,strport.toInt());  //请求连接
  }
  else
  {
      QMessageBox::warning(this,"Warning","IpAddress or Port is Null",QMessageBox::Ok);
  }
}

void Widget::ServerNewConnect()
{
  m_pTcpServerSocket = m_pTcpServer->nextPendingConnection(); //服务端接受消息
  QObject::connect(m_pTcpServerSocket, &QTcpSocket::readyRead, this, &Widget::SocketReadData);
  m_pTextEdit->append("Connect Client Success");

}

void Widget::SocketReadData()
{
  QDataStream in(m_pTcpServerSocket);
  in.setVersion(QDataStream::Qt_5_11);
  if (m_bytesReceived<=sizeof(qint64)*2){
      if((m_pTcpServerSocket->bytesAvailable()>=sizeof(qint64)*2)&&(m_fileNameSize==0)){
          in>>m_totalBytes>>m_fileNameSize;
          m_bytesReceived +=sizeof(qint64)*2;
      }

      if((m_pTcpServerSocket->bytesAvailable()>=m_fileNameSize)&&(m_fileNameSize!=0)){
                  in>>m_fileName;
                  m_bytesReceived+=m_fileNameSize;
                  m_localFile = new QFile(m_fileName);
                  if (!m_localFile->open(QFile::WriteOnly)){
                      qDebug() << "server: open file error!";
                      return;
                  }
              }
              else{
                  return;
              }
  }

  if(m_bytesReceived<m_totalBytes) {
          m_bytesReceived+=m_pTcpServerSocket->bytesAvailable();
          m_inBlock = m_pTcpServerSocket->readAll();
          m_localFile->write(m_inBlock);
          m_inBlock.resize(0);
      }


      m_pReceiverBar->setMaximum(m_totalBytes);
      m_pReceiverBar->setValue(m_bytesReceived);

      if (m_bytesReceived==m_totalBytes){
          m_localFile->close();
          QString strSuccess=QString("File %1 ReceiverSucess").arg(m_fileName);
          m_pTextEdit->append(strSuccess);
          m_pTcpServerSocket->close();
          m_totalBytes=0;
          m_bytesReceived=0;
          m_fileNameSize=0;
      }
}

void Widget::onOpenFileClicked()
{
  QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"),
                                                  "/home",
                                                  tr("File (*.*)"));
  if(fileName!="")
  {
      m_ClientfileName=fileName;
      m_pSendBtn->setEnabled(true);
      m_pFilePathEdit->setText(fileName);
  }
}

void Widget::onSendClicked()
{
  m_ClientoutBlock.clear();
  m_ClientlocalFile=new QFile(m_ClientfileName);
 if(!m_ClientlocalFile->open(QFile::ReadOnly)){
     qDebug()<<"client:open file error!";
     return;
 }
 m_ClienttotalBytes=m_ClientlocalFile->size();
 QDataStream sendOut(&m_ClientoutBlock,QIODevice::WriteOnly);
 sendOut.setVersion(QDataStream::Qt_5_11);
 QString currentFileName=m_ClientfileName.right(m_ClientfileName.size()-m_ClientfileName.lastIndexOf('/')-1);
 sendOut<<qint64(0)<<qint64(0)<<currentFileName;
 m_ClienttotalBytes+=m_ClientoutBlock.size();
 sendOut.device()->seek(0);
 sendOut<<m_ClienttotalBytes<<qint64(m_ClientoutBlock.size()-sizeof(qint64)*2);
 m_ClientbytesToWrite=m_ClienttotalBytes-m_pTcpSocket->write(m_ClientoutBlock);
 m_ClientoutBlock.resize(0);
}

void Widget::updateClientProgress(qint64 numBytes)
{
  m_ClientbytesWritten+=(int)numBytes;
  if(m_ClientbytesToWrite>0){
      m_ClientoutBlock=m_ClientlocalFile->read(qMin(m_ClientbytesToWrite,m_ClinetpayloadSize));
      m_ClientbytesToWrite-=(int)m_pTcpSocket->write(m_ClientoutBlock);
      m_ClientoutBlock.resize(0);
  }
  else{
      m_ClientlocalFile->close();
  }

  m_pSendBar->setMaximum(m_ClienttotalBytes);
  m_pSendBar->setValue(m_ClientbytesWritten);

  if(m_ClientbytesWritten==m_ClienttotalBytes){
      QString sendSuccess=QString("Send File %1 Success").arg(m_fileName);
      m_pTextEdit->append(sendSuccess);
      m_ClientlocalFile->close();
      m_pTcpSocket->close();
      m_ClientbytesWritten=0;
  }
}


这个小工具我会一直用的

到此这篇关于基于QT制作一个简易的传输文件小工具的文章就介绍到这了,更多相关QT传输文件工具内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.csdn.net/weixin_43676892/article/details/121974499

延伸 · 阅读

精彩推荐
  • C/C++C++循环链表之约瑟夫环的实现方法

    C++循环链表之约瑟夫环的实现方法

    这篇文章主要介绍了C++循环链表之约瑟夫环的实现方法,对于学习数据结构与算法有一定的借鉴价值,需要的朋友可以参考下...

    C++教程网6422021-01-30
  • C/C++c++动态内存空间示例(自定义空间类型大小和空间长度)

    c++动态内存空间示例(自定义空间类型大小和空间长度)

    这篇文章主要介绍了c++动态内存空间示例,自定义空间类型大小和空间长度,需要的朋友可以参考下...

    C++教程网9332021-01-19
  • C/C++C++ vector操作实现

    C++ vector操作实现

    这篇文章主要介绍了C++ vector操作实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来...

    刘同学_01169402021-08-06
  • C/C++VC List Control控件如何删除选中的记录实例详解

    VC List Control控件如何删除选中的记录实例详解

    这篇文章主要介绍了VC List Control控件如何删除选中的记录实例详解的相关资料,需要的朋友可以参考下...

    bianceng7952021-05-19
  • C/C++C++多重继承引发的重复调用问题与解决方法

    C++多重继承引发的重复调用问题与解决方法

    这篇文章主要介绍了C++多重继承引发的重复调用问题与解决方法,结合具体实例形式分析了C++多重调用中的重复调用问题及相应的解决方法,需要的朋友可以...

    止语---6742021-06-25
  • C/C++C语言 以字符形式读写文件详解及示例代码

    C语言 以字符形式读写文件详解及示例代码

    本文主要介绍C语言 以字符形式读写文件,这里整理了读写文件的一些资料并附示例代码,供大家学习参考,有需要的小伙伴可以参考下...

    C语言教程网5862021-04-15
  • C/C++C语言char s[]和char* s的区别

    C语言char s[]和char* s的区别

    本文主要介绍了C语言char s[]和char* s的区别,详细讲述了数组,指针的使用,具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...

    一只不出息的程序员10542021-11-18
  • C/C++QString的常用方法(小结)

    QString的常用方法(小结)

    这篇文章主要介绍了QString的常用方法(小结),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着...

    柳旭辉4422021-08-06