注意:工程监理后,因为用到网路,所以要加入对应的库
服务器:
.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 }
运行效果:
第一步:
第二步:
第三步:
第四步: