|
<div id="cnblogs_post_body"> 首先我们明确,这是一个局域网文件传输工具,具体功能实现,用网络编程,同样要设置端口号,IP地址等,这个软件已经用起来比U盘方便跟多,比平常U盘等移动存储工具的传输速率高。
传输文件数据时候,设置文件头包含信息,包括文件大小,文件名,防止出错在文件头加了个标示,读取到标识才开始传文件数据,还需要设置缓冲区,缓冲区传文件开始之前先清空。
对于文件传输来说,相当于数据先进缓冲区,之后在从缓冲区去文件数据,这样的话在接收端看到的进度条效果会比发送端进度条延后一些。

发送端

接收端

选择打开文件。

等待确认。

接收端确认

确认接收文件

接收成功。

F盘已经有文件存在。
发送端:
<div class="cnblogs_code">#include "testclient.h"#include "ui_testclient.h"#include <string>TestClient::TestClient(QWidget *parent) : QWidget(parent), ui(new Ui::TestClient){ ui->setupUi(this); socket = new QTcpSocket(); loadSize = qint64(4*1024); this->onReset(); connect(socket,SIGNAL(connected()),this,SLOT(startTransfer())); connect(socket,SIGNAL(bytesWritten(qint64)),this,SLOT(updateProgress(qint64))); connect(socket,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(displayError(QAbstractSocket::SocketError))); connect(ui->pushButton_file,SIGNAL(clicked()),this,SLOT(openFile())); connect(ui->pushButton_send,SIGNAL(clicked()),this,SLOT(onSend())); connect(ui->pushButton_abort,SIGNAL(clicked()),this,SLOT(onAbort())); connect(socket,SIGNAL(readyRead()),this,SLOT(onRead()));}TestClient::~TestClient(){ delete ui; delete socket; delete localFile;}void TestClient::openFile(){ fileName = QFileDialog::getOpenFileName(this); if(!fileName.isEmpty()) { localFile = new QFile(fileName); ui->pushButton_send->setEnabled(true); ui->pushButton_file->setDisabled(true); ui->pushButton_abort->setEnabled(true); ui->textEdit->append(tr("Open %1 success.").arg(fileName)); }}void TestClient::onSend(){ if (0 == flag) { flag = 0; ui->progressBar->reset(); ui->pushButton_send->setDisabled(true); ui->pushButton_send->setText(tr("Pause")); bytesWritten = 0; ui->textEdit->append(tr("Connecting to host.")); socket->connectToHost(ui->lineEdit_host->text(),ui->lineEdit_port->text().toInt()); if(!socket->waitForConnected(3000)) { ui->textEdit->append(tr("Connect timed out.")); return; } } else if (1 == flag) { flag = 2; ui->pushButton_send->setText(tr("Continue")); } else { flag = 1; ui->pushButton_send->setText(tr("Pause")); ui->textEdit->append(tr("Send %1 continue.").arg(currentFileName)); this->updateProgress(0); }}void TestClient::onRead(){ int length = socket->bytesAvailable(); char readBuf[10]; memset(readBuf,0,sizeof(readBuf)); socket->read(readBuf,length); //ui->textEdit->append(tr("Read %1 from host.").arg(readBuf)); if (0 == strcmp(readBuf,"yes")) { flag = 1; ui->textEdit->append(tr("Host has comfirmed. Sending %1.").arg(currentFileName)); ui->pushButton_send->setEnabled(true); this->updateProgress(0); } else { socket->abort(); localFile->close(); this->onReset(); ui->textEdit->append(tr("Send %1 failed. Host denied transfer.").arg(currentFileName)); }}void TestClient::onAbort(){ this->onReset(); ui->textEdit->append(tr("Send %1 abort.").arg(currentFileName)); socket->abort(); localFile->close();}void TestClient::onReset(){ ui->progressBar->reset(); ui->pushButton_send->setText(tr("Send")); ui->pushButton_send->setDisabled(true); ui->pushButton_abort->setDisabled(true); ui->pushButton_file->setEnabled(true); flag = 0; totalBytes = 0; bytesWritten = 0; bytesToWrite = 0;}void TestClient::startTransfer(){ if(!localFile->open(QFile::ReadOnly)) { ui->textEdit->append(tr("Open file failed.")); return; } totalBytes = localFile->size(); QDataStream sendOut(&outBlock,QIODevice::WriteOnly); sendOut.setVersion(QDataStream::Qt_4_6); currentFileName = fileName.right(fileName.size() - fileName.lastIndexOf('/')-1); sendOut << qint64(0) << qint64(0) << currentFileName; totalBytes += outBlock.size(); sendOut.device()->seek(0); sendOut<<totalBytes<<qint64((outBlock.size() - sizeof(qint64)*2)); socket->write(outBlock); socket->flush();// bytesWritten += socket->write(outBlock); bytesToWrite = totalBytes - bytesWritten; ui->progressBar->setMaximum(totalBytes); ui->textEdit->append(tr("Conected, watting for comformation.")); outBlock.resize(0); ui->pushButton_abort->setEnabled(true); ui->textEdit->append(tr("%1 of %2 . done %3 left").arg(bytesWritten).arg(totalBytes).arg(bytesToWrite));}void TestClient::updateProgress(qint64 numBytes){ bytesWritten += numBytes; if (1 == flag) { if(bytesToWrite > 0) { outBlock = localFile->read(qMin(bytesToWrite,loadSize)); bytesToWrite -= socket->write(outBlock); outBlock.resize(0); } else { ui->textEdit->append(tr("Finish sending %1 of %2 . done %3 left").arg(bytesWritten).arg(totalBytes).arg(bytesToWrite)); } if(bytesWritten == totalBytes) { this->onReset(); ui->textEdit->append(tr("Send file %1 success.").arg(currentFileName)); localFile->close(); //socket->close(); } } else { ui->textEdit->append(tr("Sending %1 puased.").arg(currentFileName)); } ui->progressBar->setValue(bytesWritten);}void TestClient::displayError(QAbstractSocket::SocketError){ if(bytesWritten != totalBytes) { this->onReset(); socket->abort(); localFile->close(); ui->textEdit->append(tr("Send %1 failed. Error: %2 .").arg(currentFileName).arg(socket->errorString())); }} |
|