1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the examples of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:BSD$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** BSD License Usage
18** Alternatively, you may use this file under the terms of the BSD license
19** as follows:
20**
21** "Redistribution and use in source and binary forms, with or without
22** modification, are permitted provided that the following conditions are
23** met:
24** * Redistributions of source code must retain the above copyright
25** notice, this list of conditions and the following disclaimer.
26** * Redistributions in binary form must reproduce the above copyright
27** notice, this list of conditions and the following disclaimer in
28** the documentation and/or other materials provided with the
29** distribution.
30** * Neither the name of The Qt Company Ltd nor the names of its
31** contributors may be used to endorse or promote products derived
32** from this software without specific prior written permission.
33**
34**
35** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
36** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
37** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
38** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
39** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
42** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
43** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
44** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
45** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
46**
47** $QT_END_LICENSE$
48**
49****************************************************************************/
50
51#ifndef TORRENTCLIENT_H
52#define TORRENTCLIENT_H
53
54#include <QBitArray>
55#include <QHostAddress>
56#include <QList>
57
58class MetaInfo;
59class PeerWireClient;
60class TorrentClientPrivate;
61struct TorrentPiece;
62QT_BEGIN_NAMESPACE
63class QTimerEvent;
64QT_END_NAMESPACE
65
66class TorrentPeer {
67public:
68 QHostAddress address;
69 quint16 port;
70 QString id;
71 bool interesting;
72 bool seed;
73 uint lastVisited;
74 uint connectStart;
75 uint connectTime;
76 QBitArray pieces;
77 int numCompletedPieces;
78
79 inline bool operator==(const TorrentPeer &other)
80 {
81 return port == other.port
82 && address == other.address
83 && id == other.id;
84 }
85};
86
87class TorrentClient : public QObject
88{
89 Q_OBJECT
90
91public:
92 enum State {
93 Idle,
94 Paused,
95 Stopping,
96 Preparing,
97 Searching,
98 Connecting,
99 WarmingUp,
100 Downloading,
101 Endgame,
102 Seeding
103 };
104 enum Error {
105 UnknownError,
106 TorrentParseError,
107 InvalidTrackerError,
108 FileError,
109 ServerError
110 };
111
112 TorrentClient(QObject *parent = nullptr);
113 ~TorrentClient();
114
115 bool setTorrent(const QString &fileName);
116 bool setTorrent(const QByteArray &torrentData);
117 MetaInfo metaInfo() const;
118
119 void setMaxConnections(int connections);
120 int maxConnections() const;
121
122 void setDestinationFolder(const QString &directory);
123 QString destinationFolder() const;
124
125 void setDumpedState(const QByteArray &dumpedState);
126 QByteArray dumpedState() const;
127
128 // Progress and stats for download feedback.
129 qint64 progress() const;
130 void setDownloadedBytes(qint64 bytes);
131 qint64 downloadedBytes() const;
132 void setUploadedBytes(qint64 bytes);
133 qint64 uploadedBytes() const;
134 int connectedPeerCount() const;
135 int seedCount() const;
136
137 // Accessors for the tracker
138 QByteArray peerId() const;
139 QByteArray infoHash() const;
140 quint16 serverPort() const;
141
142 // State and error.
143 State state() const;
144 QString stateString() const;
145 Error error() const;
146 QString errorString() const;
147
148signals:
149 void stateChanged(TorrentClient::State state);
150 void error(TorrentClient::Error error);
151
152 void downloadCompleted();
153 void peerInfoUpdated();
154
155 void dataSent(int uploadedBytes);
156 void dataReceived(int downloadedBytes);
157 void progressUpdated(int percentProgress);
158 void downloadRateUpdated(int bytesPerSecond);
159 void uploadRateUpdated(int bytesPerSecond);
160
161 void stopped();
162
163public slots:
164 void start();
165 void stop();
166 void setPaused(bool paused);
167 void setupIncomingConnection(PeerWireClient *client);
168
169protected slots:
170 void timerEvent(QTimerEvent *event) override;
171
172private slots:
173 // File management
174 void sendToPeer(int readId, int pieceIndex, int begin, const QByteArray &data);
175 void fullVerificationDone();
176 void pieceVerified(int pieceIndex, bool ok);
177 void handleFileError();
178
179 // Connection handling
180 void connectToPeers();
181 QList<TorrentPeer *> weighedFreePeers() const;
182 void setupOutgoingConnection();
183 void initializeConnection(PeerWireClient *client);
184 void removeClient();
185 void peerPiecesAvailable(const QBitArray &pieces);
186 void peerRequestsBlock(int pieceIndex, int begin, int length);
187 void blockReceived(int pieceIndex, int begin, const QByteArray &data);
188 void peerWireBytesWritten(qint64 bytes);
189 void peerWireBytesReceived(qint64 bytes);
190 int blocksLeftForPiece(const TorrentPiece *piece) const;
191
192 // Scheduling
193 void scheduleUploads();
194 void scheduleDownloads();
195 void schedulePieceForClient(PeerWireClient *client);
196 void requestMore(PeerWireClient *client);
197 int requestBlocks(PeerWireClient *client, TorrentPiece *piece, int maxBlocks);
198 void peerChoked();
199 void peerUnchoked();
200
201 // Tracker handling
202 void addToPeerList(const QList<TorrentPeer> &peerList);
203 void trackerStopped();
204
205 // Progress
206 void updateProgress(int progress = -1);
207
208private:
209 TorrentClientPrivate *d;
210 friend class TorrentClientPrivate;
211};
212
213#endif
214

source code of qtbase/examples/network/torrent/torrentclient.h