|
#include "dialog.h"
#include "ui_dialog.h"
#include <QTcpSocket>
#include <QUdpSocket>
#include <QTime>
#include <QDebug>
#include <QMessageBox>
#include <QNetworkInterface>
#include <QFile>
#include <QFileDialog>
#include <QDateTime>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <qiodevice.h>
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
setWindowTitle("client");
totalBytes = 0;
recevBytes = 0;
fileNameSize = 0;
udpSocket = new QUdpSocket(this);
uport = 8888;
u2port = 7777;
udpSocket->bind(QHostAddress::Broadcast, uport, QUdpSocket::ShareAddress| QUdpSocket::ReuseAddressHint);
connect(udpSocket, SIGNAL(readyRead()), this, SLOT(processPendingDatarams()));
tport = 6666;
cClint = new QTcpSocket(this);
connect(cClint,SIGNAL(readyRead()),this,SLOT(readMsg()));
connect(cClint, SIGNAL(error(QAbstractSocket::SocketError)), this,
SLOT(displayError(QAbstractSocket::SocketError)));
}
Dialog::~Dialog()
{
delete ui;
}
// 設(shè)置地址
void Dialog::setHostaddr(QHostAddress addr)
{
qDebug() << "--------setHostaddr---------";
hostAddr = addr;
qDebug() << "hostAddr:" << hostAddr;
newConn();
}
//設(shè)置文件名
void Dialog::setFileName(QString FileName)
{
locFile = new QFile(FileName);
}
void Dialog::newConn() // 設(shè)置與服務(wù)器建立連接的。
{
qDebug() << "---------newConn start---------";
blockSize = 0;
cClint->abort();
cClint->connectToHost(hostAddr,tport);
Time.start();
}
//接收文件
void Dialog::readMsg(){
qDebug() << "-----------readMsg start-----------";
QDataStream in(cClint);
in.setVersion(QDataStream::Qt_4_7);
float useTime = Time.elapsed();
if(recevBytes <= sizeof(qint64)*2){
if((cClint->bytesAvailable() >= sizeof(qint64)*2)&& fileNameSize == 0){
//接收數(shù)據(jù)總大小信息和數(shù)據(jù)文件名大小。
in >> totalBytes >> fileNameSize;
qDebug() << "totalBytes:" << totalBytes;
qDebug() << "fileNameSize:" << fileNameSize;
recevBytes += sizeof(qint64)*2;
qDebug() << "1recevBytes:" << recevBytes;
}
if((cClint->bytesAvailable() >= fileNameSize) && (fileNameSize != 0)){
//開始接收文件,并建立文件。
in >> FileName;
qDebug() << "FileName:" << FileName;
recevBytes += fileNameSize;
qDebug() << "2recevBytes:" << recevBytes;
if(!locFile->open(QFile::WriteOnly)){
QMessageBox::warning(this,tr("應(yīng)用程序"),tr("無法讀取文件%1: \n%2").arg(FileName).arg(locFile->errorString()));
return;
}
}else{
return;
}
}
qDebug() << "-----------BytesArray write newFile of start-----------";
if(recevBytes < totalBytes){
recevBytes += cClint->bytesAvailable(); //把緩存區(qū)的內(nèi)容寫入文件。
inBlock = cClint->readAll();
locFile->write(inBlock);
inBlock.resize(0); //清空緩存區(qū)
}
ui->progressBar->setMaximum(totalBytes);
ui->progressBar->setValue(recevBytes);//設(shè)置進度條的進度
double speed = recevBytes/useTime;
ui->label->setText(tr("(%1 m/s)").arg(speed));
qDebug() << "recevBytes:" << recevBytes;
qDebug() << "totalBytes:" << totalBytes;
if(recevBytes == totalBytes){
locFile->close();
cClint->close();
ui->label->setText(tr("接收文件 %1完畢 ").arg(FileName));
}
}
void Dialog::closeEvent(QCloseEvent *)
{
on_cClosebtn_clicked();
}
void Dialog::on_cCancelBtn_clicked()
{
cClint->abort();
if(locFile->isOpen()){
locFile->close();
}
}
void Dialog::on_cClosebtn_clicked() //關(guān)閉服務(wù)
{
cClint->abort();
if(locFile->isOpen()){
locFile->close();
}
close();
}
//處理接收到的文件名
void Dialog::hansPendingFile(QString serAddress,QString fileName)
{
QString cIpAddress = getIP(); //"192.168.31.119";
qDebug() << "cIpAddress:" << cIpAddress;
int btn = QMessageBox::information(this,tr("接收文件"),
tr("文件%1是否接收?").arg(fileName),
QMessageBox::Yes,QMessageBox::No);
if(btn == QMessageBox::Yes){
QString name = QFileDialog::getSaveFileName(0,tr("保存文件"),fileName);
if(!name.isEmpty()){
Dialog *clint = new Dialog(this);
setFileName(name);
setHostaddr(QHostAddress(serAddress));//默認一臺電腦用。
}
}
else{
SendRefuse(refuse);
sleep(2);
on_cClosebtn_clicked();
}
}
QString Dialog::getIP()
{
QList<QHostAddress> list = QNetworkInterface::allAddresses();
foreach (QHostAddress address, list) {
if(address.protocol() == QAbstractSocket::IPv4Protocol){
if(address.toString().contains("192.168.1")||address.toString().contains("127.0"))
continue;
return address.toString();
}
}
return 0;
}
//處理udp發(fā)送名字信號時函數(shù)
void Dialog::processPendingDatarams()
{
qDebug() << "pending Datarams......." ;
while(udpSocket->hasPendingDatagrams()){
QByteArray datagram;
datagram.resize(udpSocket->pendingDatagramSize());
udpSocket->readDatagram(datagram.data(), datagram.size());
QDataStream in(&datagram,QIODevice::ReadOnly);
QString time = QDateTime::currentDateTime()
.toString("yyyy-MM-dd hh:mm:ss");
//QString clientAddress, fileName;
QString fileName,serAddress;
in >> serAddress >> fileName;
qDebug() << "pending fileName" << fileName;
hansPendingFile(serAddress,fileName);
}
}
void Dialog::SendRefuse(MessageType refuse)
{
QByteArray data;
QDataStream out(&data, QIODevice::WriteOnly);
out << refuse;
qDebug() << "data" << data;
int a= udpSocket->writeDatagram(data,data.length(),QHostAddress::LocalHost, u2port);
qDebug() << "------------writeDatagram a:" << a;
}
void Dialog::displayError(QAbstractSocket::SocketError socketError)
{
switch(socketError)
{
//RemoteHostClosedError為遠處主機關(guān)閉了連接時發(fā)出的錯誤信號
case QAbstractSocket::RemoteHostClosedError : break;
default : qDebug() << cClint->errorString();
}
}
|