分享

Qt学习之路

 zkc_younger 2017-03-20
#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;
}
// 设置地址
void Dialog::setHostaddr(QHostAddress addr)
{
    qDebug() << "--------setHostaddr---------";
    hostAddr = addr;
    qDebug() << "hostAddr:" << hostAddr;
    newConn();
}
//设置文件名
void Dialog::setFileName(QString FileName)
{
    locFile = new QFile(FileName);
}
void Dialog::newConn()                   // 设置与服务器建立连接的。
{
    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){
            //接收数据总大小信息和数据文件名大小。
            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("应用程序"),tr("无法读取文件%1: \n%2").arg(FileName).arg(locFile->errorString()));
                return;
            }
        }else{
            return;
        }
    }
    qDebug() << "-----------BytesArray write newFile of start-----------";
    if(recevBytes < totalBytes){
        recevBytes += cClint->bytesAvailable();        //把缓存区的内容写入文件。
        inBlock = cClint->readAll();
        locFile->write(inBlock);
        inBlock.resize(0);                             //清空缓存区
    }
    ui->progressBar->setMaximum(totalBytes);
    ui->progressBar->setValue(recevBytes);//设置进度条的进度
    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()       //关闭服务
{
    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发送名字信号时函数
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为远处主机关闭了连接时发出的错误信号
        case QAbstractSocket::RemoteHostClosedError : break;
        default : qDebug() << cClint->errorString();
        }
}

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多