⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qftp.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the QtNetwork module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file.  Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************///#define QFTPPI_DEBUG//#define QFTPDTP_DEBUG#include "qftp.h"#include "qabstractsocket.h"#ifndef QT_NO_FTP#include "qcoreapplication.h"#include "qtcpsocket.h"#include "qurlinfo.h"#include "qstringlist.h"#include "qregexp.h"#include "qtimer.h"#include "qfileinfo.h"#include "qhash.h"#include "qtcpserver.h"class QFtpPI;/*    The QFtpDTP (DTP = Data Transfer Process) controls all client side    data transfer between the client and server.*/class QFtpDTP : public QObject{    Q_OBJECTpublic:    enum ConnectState {        CsHostFound,        CsConnected,        CsClosed,        CsHostNotFound,        CsConnectionRefused    };    QFtpDTP(QFtpPI *p, QObject *parent = 0);    void setData(QByteArray *);    void setDevice(QIODevice *);    void writeData();    void setBytesTotal(qint64 bytes);    bool hasError() const;    QString errorMessage() const;    void clearError();    void connectToHost(const QString & host, quint16 port);    int setupListener(const QHostAddress &address);    void waitForConnection();    QTcpSocket::SocketState state() const;    qint64 bytesAvailable() const;    qint64 read(char *data, qint64 maxlen);    QByteArray readAll();    void abortConnection();    static bool parseDir(const QByteArray &buffer, const QString &userName, QUrlInfo *info);signals:    void listInfo(const QUrlInfo&);    void readyRead();    void dataTransferProgress(qint64, qint64);    void connectState(int);private slots:    void socketConnected();    void socketReadyRead();    void socketError(QAbstractSocket::SocketError);    void socketConnectionClosed();    void socketBytesWritten(qint64);    void setupSocket();private:    void clearData();    QTcpSocket *socket;    QTcpServer listener;    QFtpPI *pi;    QString err;    qint64 bytesDone;    qint64 bytesTotal;    bool callWriteData;    // If is_ba is true, ba is used; ba is never 0.    // Otherwise dev is used; dev can be 0 or not.    union {        QByteArray *ba;        QIODevice *dev;    } data;    bool is_ba;    QByteArray bytesFromSocket;};/********************************************************************** * * QFtpPI - Protocol Interpreter * *********************************************************************/class QFtpPI : public QObject{    Q_OBJECTpublic:    QFtpPI(QObject *parent = 0);    void connectToHost(const QString &host, quint16 port);    bool sendCommands(const QStringList &cmds);    bool sendCommand(const QString &cmd)        { return sendCommands(QStringList(cmd)); }    void clearPendingCommands();    void abort();    QString currentCommand() const        { return currentCmd; }    bool rawCommand;    bool transferConnectionExtended;    QFtpDTP dtp; // the PI has a DTP which is not the design of RFC 959, but it                 // makes the design simpler this waysignals:    void connectState(int);    void finished(const QString&);    void error(int, const QString&);    void rawFtpReply(int, const QString&);private slots:    void hostFound();    void connected();    void connectionClosed();    void delayedCloseFinished();    void readyRead();    void error(QAbstractSocket::SocketError);    void dtpConnectState(int);private:    // the states are modelled after the generalized state diagram of RFC 959,    // page 58    enum State {        Begin,        Idle,        Waiting,        Success,        Failure    };    enum AbortState {        None,        AbortStarted,        WaitForAbortToFinish    };    bool processReply();    bool startNextCmd();    QTcpSocket commandSocket;    QString replyText;    char replyCode[3];    State state;    AbortState abortState;    QStringList pendingCommands;    QString currentCmd;    bool waitForDtpToConnect;    bool waitForDtpToClose;    QByteArray bytesFromSocket;    friend class QFtpDTP;};/********************************************************************** * * QFtpCommand implemenatation * *********************************************************************/class QFtpCommand{public:    QFtpCommand(QFtp::Command cmd, QStringList raw, const QByteArray &ba);    QFtpCommand(QFtp::Command cmd, QStringList raw, QIODevice *dev = 0);    ~QFtpCommand();    int id;    QFtp::Command command;    QStringList rawCmds;    // If is_ba is true, ba is used; ba is never 0.    // Otherwise dev is used; dev can be 0 or not.    union {        QByteArray *ba;        QIODevice *dev;    } data;    bool is_ba;    static QBasicAtomic idCounter;};QBasicAtomic QFtpCommand::idCounter = Q_ATOMIC_INIT(1);QFtpCommand::QFtpCommand(QFtp::Command cmd, QStringList raw, const QByteArray &ba)    : command(cmd), rawCmds(raw), is_ba(true){    id = idCounter.fetchAndAdd(1);    data.ba = new QByteArray(ba);}QFtpCommand::QFtpCommand(QFtp::Command cmd, QStringList raw, QIODevice *dev)    : command(cmd), rawCmds(raw), is_ba(false){    id = idCounter.fetchAndAdd(1);    data.dev = dev;}QFtpCommand::~QFtpCommand(){    if (is_ba)        delete data.ba;}/********************************************************************** * * QFtpDTP implemenatation * *********************************************************************/QFtpDTP::QFtpDTP(QFtpPI *p, QObject *parent) :    QObject(parent),    socket(0),    listener(this),    pi(p),    callWriteData(false){    clearData();    listener.setObjectName(QLatin1String("QFtpDTP active state server"));    connect(&listener, SIGNAL(newConnection()), SLOT(setupSocket()));}void QFtpDTP::setData(QByteArray *ba){    is_ba = true;    data.ba = ba;}void QFtpDTP::setDevice(QIODevice *dev){    is_ba = false;    data.dev = dev;}void QFtpDTP::setBytesTotal(qint64 bytes){    bytesTotal = bytes;    bytesDone = 0;    emit dataTransferProgress(bytesDone, bytesTotal);}void QFtpDTP::connectToHost(const QString & host, quint16 port){    bytesFromSocket.clear();    if (socket)        delete socket;    socket = new QTcpSocket(this);    socket->setObjectName(QLatin1String("QFtpDTP Passive state socket"));    connect(socket, SIGNAL(connected()), SLOT(socketConnected()));    connect(socket, SIGNAL(readyRead()), SLOT(socketReadyRead()));    connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), SLOT(socketError(QAbstractSocket::SocketError)));    connect(socket, SIGNAL(disconnected()), SLOT(socketConnectionClosed()));    connect(socket, SIGNAL(bytesWritten(qint64)), SLOT(socketBytesWritten(qint64)));    socket->connectToHost(host, port);}int QFtpDTP::setupListener(const QHostAddress &address){    if (!listener.isListening() && !listener.listen(address, 0))        return -1;    return listener.serverPort();}void QFtpDTP::waitForConnection(){    // This function is only interesting in Active transfer mode; it works    // around a limitation in QFtp's design by blocking, waiting for an    // incoming connection. For the default Passive mode, it does nothing.    if (listener.isListening())        listener.waitForNewConnection();}QTcpSocket::SocketState QFtpDTP::state() const{    return socket ? socket->state() : QTcpSocket::UnconnectedState;}qint64 QFtpDTP::bytesAvailable() const{    if (!socket || socket->state() != QTcpSocket::ConnectedState)        return (qint64) bytesFromSocket.size();    return socket->bytesAvailable();}qint64 QFtpDTP::read(char *data, qint64 maxlen){    qint64 read;    if (socket && socket->state() == QTcpSocket::ConnectedState) {        read = socket->read(data, maxlen);    } else {        read = bytesFromSocket.size();        memcpy(data, bytesFromSocket.data(), read);        bytesFromSocket.clear();    }    bytesDone += read;    return read;}QByteArray QFtpDTP::readAll(){    QByteArray tmp;    if (socket && socket->state() == QTcpSocket::ConnectedState) {        tmp = socket->readAll();        bytesDone += tmp.size();    } else {        tmp = bytesFromSocket;        bytesFromSocket.clear();    }    return tmp;}void QFtpDTP::writeData(){    if (!socket)        return;    if (is_ba) {#if defined(QFTPDTP_DEBUG)        qDebug("QFtpDTP::writeData: write %d bytes", data.ba->size());#endif        if (data.ba->size() == 0)            emit dataTransferProgress(0, bytesTotal);        else            socket->write(data.ba->data(), data.ba->size());        socket->close();        clearData();    } else if (data.dev) {        callWriteData = false;        const qint64 blockSize = 16*1024;        char buf[16*1024];        while (!data.dev->atEnd() && socket->bytesToWrite() == 0) {            qint64 read = data.dev->read(buf, blockSize);#if defined(QFTPDTP_DEBUG)            qDebug("QFtpDTP::writeData: write() of size %lli bytes", read);#endif            socket->write(buf, read);            if (!data.dev)                return; // this can happen when a command is aborted        }        if (data.dev->atEnd()) {            if (bytesDone == 0 && socket->bytesToWrite() == 0)                emit dataTransferProgress(0, bytesTotal);            socket->close();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -