一。传输文件流程
二。实现
结果:
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创建socket pTcpServer=new QTcpServer(this); //2监听--》udp这里是绑定,ip与port pTcpServer->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创建socket pTcpSocket=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); } }