桥段、 发表于 2012-12-30 12:16:17

文件传输软件

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

http://pic002.cnblogs.com/images/2012/457095/2012120714443166.png
发送端
http://pic002.cnblogs.com/images/2012/457095/2012120714451132.png
接收端
http://pic002.cnblogs.com/images/2012/457095/2012120714454436.png

选择打开文件。
http://pic002.cnblogs.com/images/2012/457095/2012120714470446.png
等待确认。

http://pic002.cnblogs.com/images/2012/457095/2012120714490178.png
接收端确认

http://pic002.cnblogs.com/images/2012/457095/2012120714462036.png

确认接收文件


http://pic002.cnblogs.com/images/2012/457095/2012120714473322.png

接收成功。

http://pic002.cnblogs.com/images/2012/457095/2012120714530911.png

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()));    }}
页: [1]
查看完整版本: 文件传输软件