服务器端和客户端都是继承于QDialog,写个主程序让他们显示即可。
代码来源于《精通Qt编程》,我觉得就是把这本书背下来,离精通还很远。代码是3个月前我自己照着pdf的书敲出来的。自己添加了一些界面代码,和一些投文件。核心代码未作修改。
有些地方我现在还没搞的很清楚,再回顾回顾学习学习。
fileTransDialog.h
#ifndef FILETRANSDIALOG_H
#define FILETRANSDIALOG_H
#include <QDialog>
#include <QtNetwork/QAbstractSocket>
#include <QPushButton>
#include <QProgressBar>
#include <QLabel>
#include <QtNetwork/QTcpSocket>
#include <QtNetwork/QHostAddress>
#include <QtGui/QDialogButtonBox>
#include <QFile>
#include <QString>
#include <QByteArray>
#include <QFileDialog>
#include <QApplication>
#include <QMessageBox>
#include <QDebug>
#include <QHBoxLayout>
#include <QVBoxLayout>
class fileTransDialog : public QDialog
{
Q_OBJECT
public:
QString strip;
fileTransDialog(QString strIP);
public slots:
void start();
void startTransfer();
void updateClientProgress(qint64 numBytes);
void displayError(QAbstractSocket::SocketError socketError);
void openFile();
private:
QProgressBar *clientProgressBar;
QLabel *clientStatusLabel;
QPushButton *startButton;
QPushButton *quitButton;
QPushButton *openButton;
QDialogButtonBox *buttonBox;
QTcpSocket tcpClient;
QHBoxLayout *hLayout;
QVBoxLayout *vLayout;
qint64 TotalBytes;
qint64 bytesWritten;
qint64 bytesToWrite;
qint64 loadSize;
QString fileName;
QFile *localFile;
QByteArray outBlock;
};
#endif // FILETRANSDIALOG_H
fileTransDialog.cpp
#include <fileTransDialog.h>
#include <QtGlobal>
fileTransDialog::fileTransDialog(QString strIP)
{
loadSize = 4*1024;
TotalBytes = 0;
bytesWritten = 0;
bytesToWrite = 0;
clientProgressBar = new QProgressBar;
clientStatusLabel = new QLabel(tr("Client has been ready"));
startButton = new QPushButton(tr("Start"));
quitButton = new QPushButton(tr("Quit"));
openButton = new QPushButton(tr("Open"));
startButton->setEnabled(false);
vLayout = new QVBoxLayout;
vLayout->addWidget(clientProgressBar);
vLayout->addWidget(clientStatusLabel);
buttonBox = new QDialogButtonBox(Qt::Horizontal);
buttonBox->addButton(startButton,QDialogButtonBox::ActionRole);
buttonBox->addButton(openButton,QDialogButtonBox::ActionRole);
buttonBox->addButton(quitButton,QDialogButtonBox::ActionRole);
hLayout = new QHBoxLayout;
hLayout->addLayout(vLayout);
vLayout->addWidget(buttonBox);
setLayout(hLayout);
connect(startButton,SIGNAL(clicked()),this,SLOT(start()));
connect(quitButton,SIGNAL(clicked()),this,SLOT(close()));
connect(openButton,SIGNAL(clicked()),this,SLOT(openFile()));
connect(&tcpClient,SIGNAL(connected()),
this,SLOT(startTransfer()));
connect(&tcpClient,SIGNAL(bytesWritten(qint64)),
this,SLOT(updateClientProgress(qint64)));
connect(&tcpClient,SIGNAL(error(QAbstractSocket::SocketError)),
this,SLOT(displayError(QAbstractSocket::SocketError)));
this->strip = strIP;
qDebug()<<this->strip;
}
void fileTransDialog::openFile()
{
fileName = QFileDialog::getOpenFileName(this);
if (!fileName.isEmpty())
startButton->setEnabled(true);
}
void fileTransDialog::start()
{
startButton->setEnabled(false);
//QApplication::setOverrideCursor(Qt::WaitCursor);
bytesWritten = 0;
clientStatusLabel->setText(tr("connecting..."));
tcpClient.connectToHost(QHostAddress(this->strip),16689);
}
void fileTransDialog::startTransfer()
{
localFile = new QFile(fileName);
if(!localFile->open(QFile::ReadOnly))
{
QMessageBox::warning(this,tr("Application"),
tr("can not open %1:\n%2.")
.arg(fileName)
.arg(localFile->errorString()));
return;
}
TotalBytes = localFile->size();
QDataStream sendOut(&outBlock,QIODevice::WriteOnly);
sendOut.setVersion(QDataStream::Qt_4_7);
QString currentFile = fileName.right(fileName.size()-
fileName.lastIndexOf('/')-1);
sendOut<<qint64(0)<<qint64(0)<<currentFile;
TotalBytes += outBlock.size();
sendOut.device()->seek(0);
sendOut<<TotalBytes<<qint64(outBlock.size()- sizeof(qint64)*2);
bytesToWrite = TotalBytes - tcpClient.write(outBlock);
clientStatusLabel->setText(tr("Connected!"));
qDebug()<<currentFile<<TotalBytes;
outBlock.resize(0);
}
void fileTransDialog::updateClientProgress(qint64 numBytes)
{
bytesWritten += (int)numBytes;
if(bytesToWrite > 0)
{
if(bytesToWrite > 0)
{
outBlock = localFile->read(qMin(bytesToWrite,loadSize));
bytesToWrite -= (int)tcpClient.write(outBlock);
outBlock.resize(0);
}
else
{
localFile->close();
}
}
clientProgressBar->setMaximum(TotalBytes);
clientProgressBar->setValue(bytesWritten);
clientStatusLabel->setText(tr("Have send %1MB").arg(bytesWritten/(1024*1024)));
}
void fileTransDialog::displayError(QAbstractSocket::SocketError socketError)
{
if(socketError == QTcpSocket::RemoteHostClosedError)
return;
QMessageBox::warning(this,tr("NetWork"),
tr("generate the following error:%1.")
.arg(tcpClient.errorString()));
tcpClient.close();
clientProgressBar->reset();
clientStatusLabel->setText(tr("Client has been ready"));
startButton->setEnabled(true);
QApplication::restoreOverrideCursor();
}
fileTransDialogS.h
#ifndef FILETRANSDIALOGS_H
#define FILETRANSDIALOGS_H
#include <QDialog>
#include <QPushButton>
#include <QLabel>
#include <QProgressBar>
#include <QDialogButtonBox>
#include <QMessageBox>
#include <QtNetwork/QAbstractSocket>
#include <QtNetwork/QTcpServer>
#include <QtNetwork/QTcpSocket>
#include <QtNetwork/QHostAddress>
#include <QFile>
#include <QApplication>
#include <QDebug>
#include <QObject>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QDataStream>
class fileTransDialogS : public QDialog
{
Q_OBJECT
public:
fileTransDialogS(QWidget *parent = 0);
private slots:
void start();
void acceptConnection();
void updateServerProgress();
void displayError(QAbstractSocket::SocketError socketError);
private:
QProgressBar *clientProgressBar;
QProgressBar *serverProgressBar;
QLabel *serverStatusLabel;
QPushButton *startButton;
QPushButton *quitButton;
QDialogButtonBox *buttonBox;
QVBoxLayout *vLay;
QHBoxLayout *hLay;
QTcpServer tcpServer;
QTcpSocket *tcpServerConnection;
qint64 TotalBytes;
qint64 bytesReceived;
qint64 fileNameSize;
QString fileName;
QFile *localFile;
QByteArray inBlock;
};
#endif // FILETRANSDIALOGS_H
fileTransDialogS.cpp
#include <fileTransDialogS.h>
#include <QString>
fileTransDialogS::fileTransDialogS(QWidget *parent)
:QDialog(parent)
{
TotalBytes = 0;
bytesReceived = 0;
fileNameSize = 0;
serverProgressBar = new QProgressBar;
serverStatusLabel = new QLabel(tr("Server has been ready"));
startButton = new QPushButton(tr("Receive"));
quitButton = new QPushButton(tr("Quit"));
buttonBox = new QDialogButtonBox;
buttonBox->addButton(startButton,QDialogButtonBox::ActionRole);
buttonBox->addButton(quitButton,QDialogButtonBox::ActionRole);
vLay = new QVBoxLayout;
vLay->addWidget(serverProgressBar);
vLay->addWidget(serverStatusLabel);
//vLay->addLayout();
hLay = new QHBoxLayout;
hLay->addWidget(buttonBox);
hLay->addLayout(vLay);
setLayout(hLay);
//..............
connect(startButton,SIGNAL(clicked()),this,SLOT(start()));
connect(quitButton,SIGNAL(clicked()),this,SLOT(close()));
connect(&tcpServer,SIGNAL(newConnection()),this,SLOT(acceptConnection()));
}
void fileTransDialogS::start()
{
startButton->setEnabled(false);
//QApplication::setOverrideCursor(Qt::WaitCursor);
bytesReceived = 0;
while(!tcpServer.isListening()&&
!tcpServer.listen(QHostAddress::LocalHost,16689))
{
QMessageBox::StandardButton ret = QMessageBox::critical(this,
tr("circle"),
tr("can not test: %1")
.arg(tcpServer.errorString()),
QMessageBox::Retry|
QMessageBox::Cancel);
if(ret == QMessageBox::Cancel)
return;
}
serverStatusLabel->setText(tr("Listening..."));
}
void fileTransDialogS::acceptConnection()
{
tcpServerConnection = tcpServer.nextPendingConnection();
connect(tcpServerConnection,SIGNAL(readyRead()),
this,SLOT(updateServerProgress()));
connect(tcpServerConnection,SIGNAL(error(QAbstractSocket::SocketError)),
this,SLOT(displayError(QAbstractSocket::SocketError)));
serverStatusLabel->setText(tr("accepted connection"));
tcpServer.close();
}
void fileTransDialogS::displayError(QAbstractSocket::SocketError socketError)
{
if(socketError == QTcpSocket::RemoteHostClosedError)
return;
QMessageBox::information(this,tr("NetWork"),
tr("generate the following error:%1.")
.arg(tcpServer.errorString()));
}
void fileTransDialogS::updateServerProgress()
{
QDataStream in(tcpServerConnection);
in.setVersion(QDataStream::Qt_4_7);
if(bytesReceived <= sizeof(qint64)*2)
{
if((tcpServerConnection->bytesAvailable() >=
sizeof(qint64)*2)&&(fileNameSize==0))
{
in>>TotalBytes>>fileNameSize;
bytesReceived += sizeof(qint64)*2;
}
if((tcpServerConnection->bytesAvailable()>=
fileNameSize)&&(fileName ==0))
{
in>>fileName;
bytesReceived += fileNameSize;
localFile = new QFile(fileName);
if(!localFile->open(QFile::WriteOnly))
{
QMessageBox::warning(this,tr("Application"),
tr("can not read file %1:\n%2.")
.arg(fileName)
.arg(localFile->errorString()));
return;
}
}
else
{
return;
}
}
if(bytesReceived<TotalBytes)
{
bytesReceived += tcpServerConnection->bytesAvailable();
inBlock = tcpServerConnection->readAll();
localFile->write(inBlock);
inBlock.resize(0);
}
serverProgressBar->setMaximum(TotalBytes);
serverProgressBar->setValue(bytesReceived);
qDebug()<<bytesReceived;
serverStatusLabel->setText(tr("Received %1MB")
.arg(bytesReceived /(1024*1024)));
if(bytesReceived == TotalBytes)
{
tcpServerConnection->close();
startButton->setEnabled(true);
startButton->setText("Complete!");
QApplication::restoreOverrideCursor();
}
}