客户端client.h
#ifndef CLIENT_H
#define CLIENT_H
#include <QWidget>
#include <QUdpSocket>
#include <QTcpSocket>
#include <QFile>
#include <QFileDialog>
#include <QProgressBar>
#include <QTimer>
#include <QDebug>
#include "stdlib.h"
namespace Ui {
class client;
}
class client : public QWidget
{
Q_OBJECT
public:
explicit client(QWidget *parent = 0);
Ui::client *ui;
~client();
private:
QTcpSocket *tcpClient;
QFile *localFile;
QPushButton *btn1,*btn2;
QDialog *dialog; //资源选择框
QPushButton *btn3;
QProgressBar *bar1;
QString filename; //保存文件路径
QByteArray outBlock; //数据缓冲区
qint64 totalBytes; //文件总字节数
qint64 fileSize; //文件名字的字节数
qint64 bytestoWrite; //尚未发送的字节数
qint64 bytesWritten; //已发送的字节数
qint64 loadSize; //每次发送数据的大小
private slots:
void updateFileProgress(qint64 numBytes); //更新文件发送进度
void send_File(); //发送文件
void select_File(); //选择文件
void startTransfer(); //发送文件大小等信息
};
#endif //
client.cpp
#include "client.h"
#include "ui_client.h"
client::client(QWidget *parent) :
QWidget(parent),
ui(new Ui::boxing)
{
ui->setupUi(this);
tcpClient = new QTcpSocket(this);
loadSize = 4*1024;
totalBytes=0;
bytestoWrite=0;
bytesWritten=0;
connect(tcpClient,SIGNAL(connected()),this,SLOT(startTransfer()));
connect(ui->pushButton,SIGNAL(clicked(bool)),this,SLOT(select_File()));//连接选择文件按钮
connect(ui->pushButton_4,SIGNAL(clicked(bool)),this,SLOT(send_File()));//连接发送文件按钮
//只要数据已写入TCP套接字,byteswritten信号就会被发出
connect(tcpClient,SIGNAL(bytesWritten(qint64)),this,SLOT(updateFileProgress(qint64)));
}
client::~client()
{
delete ui;
}
void client::select_File()
{
this->filename = QFileDialog::getOpenFileName(this,"Open a file","/a","files(*)");
bar1->setValue(0);
}
void client::send_File()
{
tcpClient->connectToHost("127.0.0.1",1234);//调试阶段用本机
}
void client::startTransfer()
{
localFile = new QFile(filename);
if(!localFile->open(QFile::ReadOnly))
{
qDdebug()<<"文件打开失败!";
return;
}
totalBytes = localFile->size(); //文件总大小
QDataStream sendout(&outBlock,QIODevice::WriteOnly);
sendout.setVersion(QDataStream::Qt_4_8);
QString currentFileName = filename.right(filename.size()-filename.lastIndexOf("/")-1);
sendout<<qint64(0)<<qint64(0)<<currentFileName; //依次写入总大小信息空间,文件名大小信息空间,文件名
totalBytes += outBlock.size(); //文件名大小和实际文件大小的总和
sendout.device()->seek(0);
//返回outblock的开始,用实际大小代替两个qint64空间
sendout<<totalBytes<<qint64((outBlock.size()-sizeof(qint64)*2));
bytestoWrite = totalBytes-tcpClient->write(outBlock);
outBlock.resize(0);
}
void client::updateFileProgress(qint64 numBytes)
{
bytesWritten += (int)numBytes;
if(bytestoWrite>0)
{
outBlock=localFile->read(qMin(bytestoWrite,loadSize));
bytestoWrite -= ((int)tcpClient->write(outBlock));
outBlock.resize(0);
}
else
{
localFile->close();
}
bar1->setMaximum(totalBytes);
bar1->setValue(bytesWritten);
dialog1->show();
if(bytesWritten == totalBytes)
{
localFile->close();
delete localFile;
disconnect(tcpClient,SIGNAL(bytesWritten(qint64)),this,SLOT(updateFileProgress(qint64)));
totalBytes=0;
bytestoWrite=0;
bytesWritten=0;
tcpClient->close();
}
}
server.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QApplication>
#include <QUdpSocket>
#include <QDebug>
#include <QThread>
#include <QTcpServer>
#include <QTcpSocket>
#include <QFile>
#include <QDataStream>
#include <QDir>
#include <QFileDialog>
#include <QSettings>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
QTcpServer *fileserver;
QTcpSocket *filesocket;
~MainWindow();
private:
QString filename; //存放文件名
QFile *localfile; //本地文件
QByteArray inBlock; //数据缓冲区
qint64 totalBytes; //文件总字节数
qint64 bytestoWrite; //尚未发送的字节数
qint64 bytesWritten; //已发送的字节数
qint64 bytesReceived; //已收到数据的大小
qint64 filenameSize; //存放文件名的大小
public slots:
void acceptFileConnection(); //建立连接
void updateFileProgres(); //更新进度,接受数据
};
#endif // MAINWINDOW_H
server.cpp
#include "mainwindow.h"
QSettings *configIni = new QSettings("config1.ini",QSettings::IniFormat);
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
filesocket = new QTcpSocket;
fileserver = new QTcpServer;
//tcp监听主代理传过来的文件信息
fileserver->listen(QHostAddress("127.0.0.1"),1234);
bytesReceived=0; //已经接受的数据包
bytesReceived=0; //已经接受的数据包
totalBytes=0;//总大小
filenameSize=0;//文件名大小
//当发现新连接时发出newConnection()信号
connect(fileserver,SIGNAL(newConnection()),this,SLOT(acceptFileConnection()));
}
MainWindow::~MainWindow()
{
delete recv_vm;
delete recv_zhu;
delete fileserver;
delete filesocket;
delete localfile;
}
void MainWindow::acceptFileConnection()
{
filesocket = fileserver->nextPendingConnection();
connect(filesocket,SIGNAL(readyRead()),this,SLOT(updateFileProgres()));//tcpsocket连接操作
}
void MainWindow::updateFileProgres()
{
QDataStream infile(filesocket);
infile.setVersion(QDataStream::Qt_4_8);
if(bytesReceived<= sizeof(qint64)*2)
{
//如果接收到的数据小于16个字节,那么是刚开始接收数据,保存到头文件
if((filesocket->bytesAvailable()>=sizeof(qint64))*2&&(filenameSize==0))
{
//总大小信息和文件名大小信息
infile>>totalBytes>>filenameSize;
bytesReceived += sizeof(qint64)*2;
}
if((filesocket->bytesAvailable()>=filenameSize)&&(filenameSize!=0))
{
//接收文件名并建立文件
infile>>filename;
bytesReceived += filenameSize;
localfile = new QFile(filename);
QString filePath ="/fff";
QDir dir(filePath);
bool exits = dir.exists(filePath);
if(exits)
{
qDebug()<<"文件夹已经存在";
}
else
{
bool ok = dir.mkdir(filePath);
if(ok)
qDebug()<<"文件夹不存在,创建成功";
}
filePath = dir.absolutePath()+QString("/%1").arg(filename);
localfile = new QFile(filePath);
if(!localfile->open(QFile::WriteOnly))
{
qDebug()<<"打开失败";
return;
}
}
else return;
}
//如果接收的数据小于总数据,那么写入文件
if(bytesReceived<totalBytes)
{
bytesReceived += filesocket->bytesAvailable();
inBlock =filesocket->readAll();
localfile->write(inBlock);
inBlock.resize(0);
}
//接收数据完成时
if(bytesReceived==totalBytes)
{
bytesReceived=0;
totalBytes=0;
filenameSize=0;
localfile->close();
}
}