一。传输文件流程
二。实现
结果:
1. server
server类属性
Ui::Widget *ui;QTcpServer* pTcpServer;QTcpSocket* pTcpSocket;//文件与文件信息QFile file;QString m_fileName;qint64 m_fileSize; //整个文件大小qint64 fileSize; //当前已经发送的文件大小bool isHead;
文件传递
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);this->setWindowTitle("服务器,文件接收端,port:6666");ui->progressBar->setValue(0);isHead=true; //接受文件的标识//1创建socketpTcpServer=new QTcpServer(this);//2监听--》udp这里是绑定,ip与portpTcpServer->listen(QHostAddress::Any,6666);fileSize=0;//3等待客户端连接connect(pTcpServer,&QTcpServer::newConnection,[=](){pTcpSocket=pTcpServer->nextPendingConnection();QString ip=pTcpSocket->peerAddress().toString();quint16 port=pTcpSocket->peerPort();QString str=QString("客户端连接服务器成功IP:%1 Port:%2").arg(ip).arg(port);ui->textEdit->setText(str);//4接受数据connect(pTcpSocket,&QTcpSocket::readyRead,[=](){QByteArray buff;buff=pTcpSocket->readAll();if(isHead){//接受文件信息--》创建文件isHead=false;m_fileName=QString(buff).section("--",0,0);m_fileSize=QString(buff).section("--",1,1).toInt();ui->textEdit->append(buff);QString tmp=QString("文件名:%1 文件大小:%2").arg(m_fileName).arg(m_fileSize);ui->textEdit->append(tmp);file.setFileName(m_fileName);bool is=file.open(QIODevice::WriteOnly);if(is){qDebug()<<"创建文件成功";}else{qDebug()<<"创建文件失败";}}else{//接受文件内容qint64 r=file.write(buff);fileSize+=r;//设置进度条ui->progressBar->setValue(100*fileSize/m_fileSize);if(fileSize>=m_fileSize){file.close();QMessageBox::information(this,"文件接受","文件接受完成");pTcpSocket->disconnect();pTcpSocket->close();}}});});}
2. client
Ui::Form *ui;QTcpSocket* pTcpSocket;QFile file;QString m_fileName; //文件名qint64 m_fileSize; //文件大小qint64 fileSize; //当前已经发送文件大小QTimer timer; //定时器//发送文件内容void sendData();
1实现client
Form::Form(QWidget *parent) :QWidget(parent),ui(new Ui::Form) {ui->setupUi(this);setWindowTitle("客户端 文件发送端");//1创建socketpTcpSocket=new QTcpSocket(this);//设置两个按钮不可按下--》不可发送,不可打开文件ui->pushButtonSend->setEnabled(false);ui->pushButtonOpen->setEnabled(false);//2监听connect(pTcpSocket,&QTcpSocket::connected,[=](){ui->textEdit->setText("连接服务器成功");ui->pushButtonOpen->setEnabled(true);});//文件信息发送后,再发送文件内容(定时器)connect(&timer,&QTimer::timeout,[=](){timer.stop();//关掉ui->textEdit->append("开始发送数据");sendData();}); } void Form::sendData(){qint64 r=0;char buff[1024];while(1){r = file.read(buff,1024);//从文件中读取if(r<=0) break;r = pTcpSocket->write(buff,r);//发给接收端if(r <=0 ) break;fileSize += r;//累加已经发送的文件大小}qDebug()<<"文件传递成功"; }
tcp连接
void Form::on_pushButtonConnect_clicked() {QString ip=ui->lineEditIP->text();quint16 port=ui->lineEditPORT->text().toUInt();pTcpSocket->connectToHost(ip,port); }
打开文件
void Form::on_pushButtonOpen_clicked() {QString fileName=QFileDialog::getOpenFileName(this,"打开发送文件","C:/Users/Administrator/Desktop","TXT(*.txt);;""DOC(*.doc,*.doxc);;""MP4(*.mp4);;""ALL(*.*)");if(!fileName.isEmpty()){m_fileName.clear();m_fileSize=0;fileSize=0;//文件信息QFileInfo info(fileName);m_fileName=info.fileName();m_fileSize=info.size();QString str=QString("文件名%1 文件大小%2").arg(m_fileName).arg(m_fileSize);ui->textEdit->append(str);//打开文件file.setFileName(fileName);//注意用带路径的文件名bool is=file.open(QIODevice::ReadOnly);if(is){ui->textEdit->append("准备发送文件路径");ui->textEdit->append(fileName);ui->pushButtonSend->setEnabled(true);ui->pushButtonOpen->setEnabled(false);}else{qDebug()<<"打开文件失败";}}else{qDebug()<<"获取文件失败";} }
发送文件消息触发
void Form::on_pushButtonSend_clicked() {QString fileHead=QString("%1--%2").arg(m_fileName).arg(m_fileSize);qint64 ret=pTcpSocket->write(fileHead.toUtf8());if(ret>0){qDebug()<<"文件发送信息成功";timer.start(20);//定时器20ms发送}else{qDebug()<<"发送文件信息失败";file.close();ui->pushButtonSend->setEnabled(false);ui->pushButtonOpen->setEnabled(true);} }