Home · All Classes · Main Classes · Grouped Classes · Modules · Functions

peerwireclient.h Example File
network/torrent/peerwireclient.h

 /****************************************************************************
 **
 ** Copyright (C) 2004-2008 Trolltech ASA. All rights reserved.
 **
 ** This file is part of the example classes of the Qt Toolkit.
 **
 ** Licensees holding a valid Qt License Agreement may use this file in
 ** accordance with the rights, responsibilities and obligations
 ** contained therein.  Please consult your licensing agreement or
 ** contact sales@trolltech.com if any conditions of this licensing
 ** agreement are not clear to you.
 **
 ** Further information about Qt licensing is available at:
 ** http://www.trolltech.com/products/qt/licensing.html or by
 ** contacting info@trolltech.com.
 **
 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 **
 ****************************************************************************/

 #ifndef PEERWIRECLIENT_H
 #define PEERWIRECLIENT_H

 class QHostAddress;
 class QTimerEvent;
 class TorrentPeer;

 #include <QBitArray>
 #include <QList>
 #include <QTcpSocket>

 struct TorrentBlock
 {
     inline TorrentBlock(int p, int o, int l)
         : pieceIndex(p), offset(o), length(l)
     {
     }
     inline bool operator==(const TorrentBlock &other) const
     {
         return pieceIndex == other.pieceIndex
                 && offset == other.offset
                 && length == other.length;
     }

     int pieceIndex;
     int offset;
     int length;
 };

 class PeerWireClient : public QTcpSocket
 {
     Q_OBJECT

 public:
     enum PeerWireStateFlag {
         ChokingPeer = 0x1,
         InterestedInPeer = 0x2,
         ChokedByPeer = 0x4,
         PeerIsInterested = 0x8
     };
     Q_DECLARE_FLAGS(PeerWireState, PeerWireStateFlag)

     PeerWireClient(const QByteArray &peerId, QObject *parent = 0);
     void initialize(const QByteArray &infoHash, int pieceCount);

     void setPeer(TorrentPeer *peer);
     TorrentPeer *peer() const;

     // State
     inline PeerWireState peerWireState() const { return pwState; }
     QBitArray availablePieces() const;
     QList<TorrentBlock> incomingBlocks() const;

     // Protocol
     void chokePeer();
     void unchokePeer();
     void sendInterested();
     void sendKeepAlive();
     void sendNotInterested();
     void sendPieceNotification(int piece);
     void sendPieceList(const QBitArray &bitField);
     void requestBlock(int piece, int offset, int length);
     void cancelRequest(int piece, int offset, int length);
     void sendBlock(int piece, int offset, const QByteArray &data);

     // Rate control
     qint64 writeToSocket(qint64 bytes);
     qint64 readFromSocket(qint64 bytes);
     qint64 downloadSpeed() const;
     qint64 uploadSpeed() const;

     bool canTransferMore() const;
     qint64 bytesAvailable() const { return incomingBuffer.size() + QTcpSocket::bytesAvailable(); }
     qint64 socketBytesAvailable() const { return socket.bytesAvailable(); }
     qint64 socketBytesToWrite() const { return socket.bytesToWrite(); }

     void setReadBufferSize(int size);

 signals:
     void infoHashReceived(const QByteArray &infoHash);
     void readyToTransfer();

     void choked();
     void unchoked();
     void interested();
     void notInterested();

     void piecesAvailable(const QBitArray &pieces);
     void blockRequested(int pieceIndex, int begin, int length);
     void blockReceived(int pieceIndex, int begin, const QByteArray &data);

     void bytesReceived(qint64 size);

 protected slots:
     void connectToHostImplementation(const QString &hostName,
                                      quint16 port, OpenMode openMode = ReadWrite);
     void diconnectFromHostImplementation();

 protected:
     void timerEvent(QTimerEvent *event);

     qint64 readData(char *data, qint64 maxlen);
     qint64 readLineData(char *data, qint64 maxlen);
     qint64 writeData(const char *data, qint64 len);

 private slots:
     void sendHandShake();
     void processIncomingData();
     void socketStateChanged(QAbstractSocket::SocketState state);

 private:
     // Data waiting to be read/written
     QByteArray incomingBuffer;
     QByteArray outgoingBuffer;

     struct BlockInfo {
         int pieceIndex;
         int offset;
         int length;
         QByteArray block;
     };
     QList<BlockInfo> pendingBlocks;
     int pendingBlockSizes;
     QList<TorrentBlock> incoming;

     enum PacketType {
         ChokePacket = 0,
         UnchokePacket = 1,
         InterestedPacket = 2,
         NotInterestedPacket = 3,
         HavePacket = 4,
         BitFieldPacket = 5,
         RequestPacket = 6,
         PiecePacket = 7,
         CancelPacket = 8
     };

     // State
     PeerWireState pwState;
     bool receivedHandShake;
     bool gotPeerId;
     bool sentHandShake;
     int nextPacketLength;

     // Upload/download speed records
     qint64 uploadSpeedData[8];
     qint64 downloadSpeedData[8];
     int transferSpeedTimer;

     // Timeout handling
     int timeoutTimer;
     int pendingRequestTimer;
     bool invalidateTimeout;
     int keepAliveTimer;

     // Checksum, peer ID and set of available pieces
     QByteArray infoHash;
     QByteArray peerIdString;
     QBitArray peerPieces;
     TorrentPeer *torrentPeer;

     QTcpSocket socket;
 };

 Q_DECLARE_OPERATORS_FOR_FLAGS(PeerWireClient::PeerWireState)

 #endif


Copyright © 2008 Trolltech Trademarks
Qt 4.3.5