#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è)置進(jìn)度條的進(jìn)度
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)); //默認(rèn)一臺(tái)電腦用。
}
}
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ā)送名字信號(hào)時(shí)函數(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為遠(yuǎn)處主機(jī)關(guān)閉了連接時(shí)發(fā)出的錯(cuò)誤信號(hào)
case QAbstractSocket::RemoteHostClosedError : break ;
default : qDebug() << cClint->errorString();
}
}
|