• QT笔记之VS2012 TCP传送文件


    注意:工程监理后,因为用到网路,所以要加入对应的库

    服务器:

    .h

     1 #ifndef TCPFILE_H
     2 #define TCPFILE_H
     3 
     4 #include <QtWidgets/QWidget>
     5 #include "ui_tcpfile.h"
     6 #include <QtNetwork/QTcpServer>//监听套接字
     7 #include <QtNetwork/QTcpSocket>//通信套接字
     8 #include <QFile>
     9 #include <QTimer>
    10 
    11 
    12 class TCPFile : public QWidget
    13 {
    14     Q_OBJECT
    15 
    16 public:
    17     TCPFile(QWidget *parent = 0);
    18     ~TCPFile();
    19 
    20     void SendData();//发送文件数据函数
    21 
    22 private slots:
    23     void on_buttonSelect_clicked();
    24 
    25     void on_buttonSend_clicked();
    26 
    27     
    28 
    29 private:
    30     Ui::TCPFileClass ui;
    31 
    32     QTcpServer* tcpServer;//监听套接字
    33     QTcpSocket* tcpSocket;//通信套接字
    34 
    35     QFile file;//文件对象
    36     QString filename;//文件名字
    37     qint64 filesize;//文件大小
    38     qint64 sendsize;//已发送文件大小
    39 
    40     QTimer timer;//定时器
    41 };
    42 
    43 #endif // TCPFILE_H

    .cpp

      1 #include "tcpfile.h"
      2 #include <QTextCodec>
      3 #include <QFileDialog>//选择文件对话框
      4 #include <QDebug>
      5 #include <QFileInfo>//文件信息
      6 
      7 TCPFile::TCPFile(QWidget *parent)
      8     : QWidget(parent)
      9 {
     10     ui.setupUi(this);
     11 
     12     //监听套接字
     13     tcpServer = new QTcpServer(this);
     14 
     15     //监听
     16     tcpServer->listen(QHostAddress::Any,8888);
     17 
     18     QTextCodec *codec = QTextCodec::codecForLocale();//解决中文乱码
     19 
     20     QString Titleinfo = codec->toUnicode("服务器端口为:8888");
     21 
     22     setWindowTitle(Titleinfo);
     23 
     24     //建立连接之前两个按钮不可用
     25     ui.buttonSelect->setEnabled(false);
     26     ui.buttonSend->setEnabled(false);
     27 
     28     //如果客户端和服务器连接
     29     //tcpServer会自动触发 newConnection()
     30 
     31     connect(tcpServer,&QTcpServer::newConnection,
     32         [=]()
     33     {
     34         //取出建立好连接的套接字
     35         tcpSocket = tcpServer->nextPendingConnection();
     36 
     37         //获取对方的ip和port
     38         QString strIP = tcpSocket->peerAddress().toString();
     39         quint16 port = tcpSocket->peerPort();
     40 
     41         QString str = QStringLiteral("[%1,%2] 成功连接").arg(strIP).arg(port);
     42         //str = codec->toUnicode(str);
     43 
     44         ui.textEdit->setText(str);//显示到编辑框
     45 
     46         //成功连接后 选择按钮可用
     47 
     48         ui.buttonSelect->setEnabled(true);
     49     }
     50     );
     51 
     52     connect(&timer,&QTimer::timeout,
     53         [=]()
     54     {
     55         //关闭定时器
     56         timer.stop();
     57         SendData();
     58     }
     59     );
     60 }
     61 
     62 TCPFile::~TCPFile()
     63 {
     64 
     65 }
     66 
     67 void TCPFile::on_buttonSelect_clicked()
     68 {
     69     QString filepath = QFileDialog::getOpenFileName(this,"open","../");
     70 
     71     if(!filepath.isEmpty())
     72     {
     73         //文件路径有效
     74         //只读方式打开文件
     75         filename.clear();
     76         filesize = 0;
     77 
     78         QFileInfo info(filepath);//获取文件信息
     79         filename = info.fileName();
     80         filesize = info.size();
     81 
     82         sendsize = 0;//发送文件的大小
     83 
     84         file.setFileName(filepath);
     85 
     86         //打开文件
     87 
     88         bool isOk = file.open(QIODevice::ReadOnly);
     89 
     90         if(false == isOk)
     91         {
     92             qDebug() << "只读方式打开文件失败";
     93         }
     94         else
     95         {
     96             //提示打开文件的路径
     97             ui.textEdit->append(filepath);
     98             ui.buttonSelect->setEnabled(false);
     99             ui.buttonSend->setEnabled(true);
    100 
    101 
    102         }
    103     }
    104 }
    105 
    106 void TCPFile::on_buttonSend_clicked()
    107 {
    108     //先发送文件头部信息
    109     QString head = QString("%1##%2").arg(filename).arg(filesize);//自定义文件头部
    110 
    111     //发送头部信息
    112     qint64 len = tcpSocket->write(head.toUtf8());
    113     if(len > 0)//头部信息发送成功
    114     {
    115         //发送真正的文件信息
    116         //防止TCP粘包文件
    117         //需要通过定时器延时 20ms
    118 
    119 
    120         timer.start(20);
    121     }
    122     else
    123     {
    124         qDebug() << "头部信息发送失败 115";
    125         file.close();
    126 
    127         ui.buttonSelect->setEnabled(true);
    128         ui.buttonSend->setEnabled(false);
    129     }
    130 }
    131 
    132 
    133 void TCPFile::SendData()
    134 {
    135     qint64 len = 0;
    136 
    137     do
    138     {
    139         //每次发送数据的大小
    140         char buf[4*1024] = {0};
    141         len = 0;
    142 
    143         //往文件中读数据
    144         len =  file.read(buf,sizeof(buf));
    145         //发送数据 读多少  发送多少
    146 
    147         //发送多好
    148         len = tcpSocket->write(buf,len);
    149         sendsize += len;
    150     }while(len > 0);
    151 
    152 
    153     if(sendsize == filesize)
    154     {
    155         ui.textEdit->append("file finshed");
    156         file.close();
    157 
    158         //把客户端断开连接
    159         tcpSocket->disconnectFromHost();
    160         tcpSocket->close();
    161     }
    162 }

    客户端

    .h

     1 #ifndef CLIENTWIDGET_H
     2 #define CLIENTWIDGET_H
     3 
     4 #include <QWidget>
     5 #include "ui_clientwidget.h"
     6 #include <QtNetwork/QTcpSocket>//通信套接字
     7 #include <QFile>
     8 
     9 class ClientWidget : public QWidget
    10 {
    11     Q_OBJECT
    12 
    13 public:
    14     ClientWidget(QWidget *parent = 0);
    15     ~ClientWidget();
    16 
    17 private slots:
    18     void on_buttonConnect_clicked();
    19 
    20 private:
    21     Ui::ClientWidget ui;
    22 
    23     QTcpSocket* tcpSocket;//通信套接字
    24 
    25     QFile file;//文件对象
    26     QString filename;//文件名字
    27     qint64 filesize;//文件大小
    28     qint64 recvsize;//已接收文件大小
    29 
    30     bool isHead;//是否是头
    31 };
    32 
    33 #endif // CLIENTWIDGET_H

    .cpp

     1 #include "clientwidget.h"
     2 #include <QMessageBox>
     3 #include <QHostAddress>
     4 #include <QTextCodec>
     5 
     6 ClientWidget::ClientWidget(QWidget *parent)
     7     : QWidget(parent)
     8 {
     9     ui.setupUi(this);
    10 
    11     tcpSocket = new QTcpSocket(this);
    12 
    13     setWindowTitle(QStringLiteral("客户端"));
    14 
    15     isHead = true;
    16 
    17     QTextCodec *codec = QTextCodec::codecForLocale();//解决中文乱码
    18 
    19     connect(tcpSocket,&QTcpSocket::readyRead,
    20         [=]()
    21          {
    22              //取出接收到的东西
    23              QByteArray buf = tcpSocket->readAll();
    24 
    25              if (isHead)
    26              {//接收头
    27                  isHead = false;
    28                  //解析头部信息 QString buf = "hello##1024";  文件名为 "hello" 大小为 1024
    29                  // QString str ="hello##1024";
    30                  //str.section("##",0,0); 取出 "hello" 
    31                  //str.section("##",1,1); 取出 "1024"
    32 
    33                  filename = QString(buf).section("##", 0, 0);
    34                  filesize = QString(buf).section("##", 1, 1).toInt();
    35                  recvsize = 0;
    36 
    37                  //初始化
    38                  //打开文件
    39 
    40                  file.setFileName(filename);
    41 
    42                  bool isOk = file.open(QIODevice::WriteOnly);
    43 
    44                  if (false == isOk)
    45                  {
    46                      QMessageBox::information(this,"打开","文件打开失败");
    47                  }
    48 
    49              }
    50              else
    51              {
    52                  //文件信息
    53                  qint64 len = file.write(buf);
    54 
    55                  recvsize += len;
    56 
    57                  if (recvsize == filesize)
    58                  {
    59                      file.close();
    60                      QString title = codec->toUnicode("完成");
    61                      QString info = codec->toUnicode("接收完成");
    62                      QMessageBox::information(this,title,info);
    63 
    64                      //断开连接
    65                      tcpSocket->disconnectFromHost();
    66                     tcpSocket->close();
    67                  }
    68 
    69              }
    70          }
    71         );
    72 }
    73 
    74 ClientWidget::~ClientWidget()
    75 {
    76 
    77 }
    78 
    79 void ClientWidget::on_buttonConnect_clicked()
    80 {
    81      //获取服务器的IP和端口
    82 
    83     QString strIP = ui.lineEditIP->text();
    84     quint16 port =  ui.lineEditPort->text().toInt();
    85 
    86     tcpSocket->connectToHost(QHostAddress(strIP),port);
    87 }

    main文件

     1 #include "tcpfile.h"
     2 #include <QtWidgets/QApplication>
     3 #include "clientwidget.h"
     4 
     5 int main(int argc, char *argv[])
     6 {
     7     QApplication a(argc, argv);
     8     TCPFile w;
     9     w.show();
    10 
    11     ClientWidget cw;
    12     cw.show();
    13 
    14     return a.exec();
    15 }

    运行效果:

    第一步:

    第二步:

    第三步:

    第四步:

  • 相关阅读:
    可视化百分比数据,Excel图表展示小技巧
    巧用宏录制,轻松制作Excel简易查询小系统
    Excel也能制作电子印章,你见过吗?学会了职场不求人
    ​21个Shift组合快捷键,学会了想加班都难
    Excel中关于日期时间的小知识小技巧,你还记得多少?
    自动添加单元格边框,Excel有妙招,两个技巧任意选
    [asp.net] 通过JS实现对treeview控件的复选框单选控制。
    编译器把getset访问器编译成了方法get_method()/set_method()
    sql MERGE
    动态添加特性
  • 原文地址:https://www.cnblogs.com/chechen/p/6100893.html
Copyright © 2020-2023  润新知