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

📄 download_main.cc

📁 LibTorrent is a BitTorrent library written in C++ for *nix, with a focus on high performance and goo
💻 CC
字号:
// libTorrent - BitTorrent library// Copyright (C) 2005-2006, Jari Sundell//// This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.// // This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the// GNU General Public License for more details.// // You should have received a copy of the GNU General Public License// along with this program; if not, write to the Free Software// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA//// In addition, as a special exception, the copyright holders give// permission to link the code of portions of this program with the// OpenSSL library under certain conditions as described in each// individual source file, and distribute linked combinations// including the two.//// You must obey the GNU General Public License in all respects for// all of the code used other than OpenSSL.  If you modify file(s)// with this exception, you may extend this exception to your version// of the file(s), but you are not obligated to do so.  If you do not// wish to do so, delete this exception statement from your version.// If you delete this exception statement from all source files in the// program, then also delete it here.//// Contact:  Jari Sundell <jaris@ifi.uio.no>////           Skomakerveien 33//           3185 Skoppum, NORWAY#include "config.h"#include <cstring>#include <limits>#include "data/chunk_list.h"#include "protocol/handshake_manager.h"#include "protocol/peer_connection_base.h"#include "tracker/tracker_manager.h"#include "torrent/exceptions.h"#include "available_list.h"#include "choke_manager.h"#include "chunk_selector.h"#include "chunk_statistics.h"#include "download_info.h"#include "download_main.h"namespace torrent {DownloadMain::DownloadMain() :  m_info(new DownloadInfo),  m_trackerManager(new TrackerManager()),  m_chunkList(new ChunkList),  m_chunkSelector(new ChunkSelector),  m_chunkStatistics(new ChunkStatistics),  m_uploadThrottle(NULL),  m_downloadThrottle(NULL) {  m_connectionList = new ConnectionList(this);  m_chokeManager = new ChokeManager(m_connectionList);  m_delegator.slot_chunk_find(rak::make_mem_fun(m_chunkSelector, &ChunkSelector::find));  m_delegator.slot_chunk_size(rak::make_mem_fun(&m_content, &Content::chunk_index_size));  m_delegator.transfer_list()->slot_canceled(std::bind1st(std::mem_fun(&ChunkSelector::not_using_index), m_chunkSelector));  m_delegator.transfer_list()->slot_queued(std::bind1st(std::mem_fun(&ChunkSelector::using_index), m_chunkSelector));  m_delegator.transfer_list()->slot_completed(std::bind1st(std::mem_fun(&DownloadMain::receive_chunk_done), this));  m_delegator.transfer_list()->slot_corrupt(std::bind1st(std::mem_fun(&DownloadMain::receive_corrupt_chunk), this));  m_taskTrackerRequest.set_slot(rak::mem_fn(this, &DownloadMain::receive_tracker_request));  m_chunkList->slot_create_chunk(rak::make_mem_fun(&m_content, &Content::create_chunk));  m_chunkList->slot_free_diskspace(rak::make_mem_fun(m_content.entry_list(), &EntryList::free_diskspace));}DownloadMain::~DownloadMain() {  if (m_taskTrackerRequest.is_queued())    throw internal_error("DownloadMain::~DownloadMain(): m_taskTrackerRequest is queued.");  delete m_trackerManager;  delete m_chokeManager;  delete m_connectionList;  delete m_chunkStatistics;  delete m_chunkList;  delete m_chunkSelector;  delete m_info;}voidDownloadMain::open() {  if (info()->is_open())    throw internal_error("Tried to open a download that is already open");  m_content.entry_list()->open();  m_chunkList->resize(m_content.chunk_total());  m_chunkStatistics->initialize(m_content.chunk_total());  info()->set_open(true);}voidDownloadMain::close() {  if (info()->is_active())    throw internal_error("Tried to close an active download");  if (!info()->is_open())    return;  info()->set_open(false);  m_trackerManager->close();  m_delegator.transfer_list()->clear();  m_content.bitfield()->unallocate();  m_content.entry_list()->close();  // Clear the chunklist last as it requires all referenced chunks to  // be released.  m_chunkStatistics->clear();  m_chunkList->clear();  m_chunkSelector->cleanup();}void DownloadMain::start() {  if (!info()->is_open())    throw client_error("Tried to start a closed download");  if (info()->is_active())    throw client_error("Tried to start an active download");  info()->set_active(true);  m_lastConnectedSize = 0;  m_delegator.set_aggressive(false);  update_endgame();    receive_connect_peers();}  voidDownloadMain::stop() {  if (!info()->is_active())    return;  // Set this early so functions like receive_connect_peers() knows  // not to eat available peers.  info()->set_active(false);  m_slotStopHandshakes(this);  connection_list()->erase_remaining(connection_list()->begin(), ConnectionList::disconnect_available);  priority_queue_erase(&taskScheduler, &m_taskTrackerRequest);}voidDownloadMain::update_endgame() {  if (!m_delegator.get_aggressive() && m_content.chunks_completed() + m_delegator.transfer_list()->size() + 5 >= m_content.chunk_total())    m_delegator.set_aggressive(true);}voidDownloadMain::receive_chunk_done(unsigned int index) {  ChunkHandle handle = m_chunkList->get(index, false);  if (!handle.is_valid())    throw storage_error("DownloadState::chunk_done(...) called with an index we couldn't retrieve from storage");  m_slotHashCheckAdd(handle);}voidDownloadMain::receive_corrupt_chunk(PeerInfo* peerInfo) {  peerInfo->set_failed_counter(peerInfo->failed_counter() + 1);  // Just use some very primitive heuristics here to decide if we're  // going to disconnect the peer. Also, consider adding a flag so we  // don't recalculate these things whenever the peer reconnects.  // That is... non at all ;)  connection_list()->erase(peerInfo, ConnectionList::disconnect_unwanted);}voidDownloadMain::receive_connect_peers() {  if (!info()->is_active())    return;  AvailableList::AddressList* alist = peer_list()->available_list()->buffer();  if (!alist->empty()) {    alist->sort();    peer_list()->available_list()->insert(alist);    alist->clear();  }  while (!peer_list()->available_list()->empty() &&         connection_list()->size() < connection_list()->get_min_size() &&         connection_list()->size() + m_slotCountHandshakes(this) < connection_list()->get_max_size()) {    rak::socket_address sa = peer_list()->available_list()->pop_random();    if (connection_list()->find(sa) == connection_list()->end())      m_slotStartHandshake(sa, this);  }}voidDownloadMain::receive_tracker_success() {  if (!info()->is_active())    return;  priority_queue_erase(&taskScheduler, &m_taskTrackerRequest);  priority_queue_insert(&taskScheduler, &m_taskTrackerRequest, (cachedTime + rak::timer::from_seconds(30)).round_seconds());}voidDownloadMain::receive_tracker_request() {  if (connection_list()->size() >= connection_list()->get_min_size())    return;  if (connection_list()->size() < m_lastConnectedSize + 10 ||      !m_trackerManager->request_current())    // Try the next tracker if we couldn't get enough peers from the    // current one, or if we have connected more than    // TrackerManager::max_num_request times.    m_trackerManager->request_next();  m_lastConnectedSize = connection_list()->size();}}

⌨️ 快捷键说明

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