赞助

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 }

 

运行效果:

第一步:

第二步:

第三步:

第四步:

 

posted @ 2016-11-25 11:20  车臣  阅读(2006)  评论(0编辑  收藏  举报