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

📄 peer_connection_base.cc

📁 LibTorrent is a BitTorrent library written in C++ for *nix, with a focus on high performance and goo
💻 CC
📖 第 1 页 / 共 2 页
字号:
  m_download->download_throttle()->node_used(m_peerChunks.download_throttle(), bytesTransfered);  m_download->info()->down_rate()->insert(bytesTransfered);  return transfer->is_finished();}boolPeerConnectionBase::down_chunk_from_buffer() {  m_down->buffer()->move_position(down_chunk_process(m_down->buffer()->position(), m_down->buffer()->remaining()));  if (!m_downloadQueue.transfer()->is_finished() && m_down->buffer()->remaining() != 0)    throw internal_error("PeerConnectionBase::down_chunk_from_buffer() !transfer->is_finished() && m_down->buffer()->remaining() != 0.");  return m_downloadQueue.transfer()->is_finished();}  // When this transfer again becomes the leader, we just return false// and wait for the next polling. It is an exceptional case so we// don't really care that much about performance.boolPeerConnectionBase::down_chunk_skip() {  uint32_t length = read_stream_throws(m_nullBuffer, m_downloadQueue.transfer()->piece().length() - m_downloadQueue.transfer()->position());  if (down_chunk_skip_process(m_nullBuffer, length) != length)    throw internal_error("PeerConnectionBase::down_chunk_skip() down_chunk_skip_process(m_nullBuffer, length) != length.");  return m_downloadQueue.transfer()->is_finished();}boolPeerConnectionBase::down_chunk_skip_from_buffer() {  m_down->buffer()->move_position(down_chunk_skip_process(m_down->buffer()->position(), m_down->buffer()->remaining()));    return m_downloadQueue.transfer()->is_finished();}// Process data from a leading transfer.uint32_tPeerConnectionBase::down_chunk_process(const void* buffer, uint32_t length) {  if (!m_downChunk.is_valid() || m_downChunk.index() != m_downloadQueue.transfer()->index())    throw internal_error("PeerConnectionBase::down_chunk_process(...) !m_downChunk.is_valid() || m_downChunk.index() != m_downloadQueue.transfer()->index().");  if (length == 0)    return length;  BlockTransfer* transfer = m_downloadQueue.transfer();  length = std::min(transfer->piece().length() - transfer->position(), length);  m_downChunk.chunk()->from_buffer(buffer, transfer->piece().offset() + transfer->position(), length);  transfer->adjust_position(length);  m_download->download_throttle()->node_used(m_peerChunks.download_throttle(), length);  m_download->info()->down_rate()->insert(length);  return length;}// Process data from non-leading transfer. If this transfer encounters// mismatching data with the leader then bork this transfer. If we get// ahead of the leader, we switch the leader.uint32_tPeerConnectionBase::down_chunk_skip_process(const void* buffer, uint32_t length) {  BlockTransfer* transfer = m_downloadQueue.transfer();  // Adjust 'length' to be less than or equal to what is remaining of  // the block to simplify the rest of the function.  length = std::min(length, transfer->piece().length() - transfer->position());  m_download->download_throttle()->node_used(m_peerChunks.download_throttle(), length);  m_download->info()->down_rate()->insert(length);  if (!transfer->is_valid()) {    transfer->adjust_position(length);    return length;  }  if (!transfer->block()->is_transfering())    throw internal_error("PeerConnectionBase::down_chunk_skip_process(...) block is not transfering, yet we have non-leaders.");  // Temporary test.  if (transfer->position() > transfer->block()->leader()->position())    throw internal_error("PeerConnectionBase::down_chunk_skip_process(...) transfer is past the Block's position.");  // If the transfer is valid, compare the downloaded data to the  // leader.  uint32_t compareLength = std::min(length, transfer->block()->leader()->position() - transfer->position());  // The data doesn't match with what has previously been downloaded,  // bork this transfer.  if (!m_downChunk.chunk()->compare_buffer(buffer, transfer->piece().offset() + transfer->position(), compareLength)) {    m_download->info()->signal_network_log().emit("Data does not match what was previously downloaded.");        m_downloadQueue.transfer_dissimilar();    m_downloadQueue.transfer()->adjust_position(length);    return length;  }  transfer->adjust_position(compareLength);  if (compareLength == length)    return length;  // Add another check here to see if we really want to be the new  // leader.  transfer->block()->change_leader(transfer);  if (down_chunk_process(static_cast<const char*>(buffer) + compareLength, length - compareLength) != length - compareLength)    throw internal_error("PeerConnectionBase::down_chunk_skip_process(...) down_chunk_process(...) returned wrong value.");    return length;}boolPeerConnectionBase::up_chunk() {  if (!m_download->upload_throttle()->is_throttled(m_peerChunks.upload_throttle()))    throw internal_error("PeerConnectionBase::up_chunk() tried to write a piece but is not in throttle list");  if (!m_upChunk.chunk()->is_readable())    throw internal_error("ProtocolChunk::write_part() chunk not readable, permission denided");  uint32_t quota = m_download->upload_throttle()->node_quota(m_peerChunks.upload_throttle());  if (quota == 0) {    manager->poll()->remove_write(this);    m_download->upload_throttle()->node_deactivate(m_peerChunks.upload_throttle());    return false;  }  uint32_t bytesTransfered = 0;  Chunk::data_type data;  ChunkIterator itr(m_upChunk.chunk(), m_upPiece.offset(), m_upPiece.offset() + std::min(quota, m_upPiece.length()));  do {    data = itr.data();    data.second = write_stream_throws(data.first, data.second);    bytesTransfered += data.second;  } while (itr.used(data.second));  m_download->upload_throttle()->node_used(m_peerChunks.upload_throttle(), bytesTransfered);  m_download->info()->up_rate()->insert(bytesTransfered);  // Just modifying the piece to cover the remaining data ends up  // being much cleaner and we avoid an unnessesary position variable.  m_upPiece.set_offset(m_upPiece.offset() + bytesTransfered);  m_upPiece.set_length(m_upPiece.length() - bytesTransfered);  return m_upPiece.length() == 0;}voidPeerConnectionBase::down_chunk_release() {  if (m_downChunk.is_valid())    m_download->chunk_list()->release(&m_downChunk);}voidPeerConnectionBase::up_chunk_release() {  if (m_upChunk.is_valid())    m_download->chunk_list()->release(&m_upChunk);}voidPeerConnectionBase::read_request_piece(const Piece& p) {  PeerChunks::piece_list_type::iterator itr = std::find(m_peerChunks.upload_queue()->begin(), m_peerChunks.upload_queue()->end(), p);    if (m_up->choked() || itr != m_peerChunks.upload_queue()->end() || p.length() > (1 << 17))    return;  m_peerChunks.upload_queue()->push_back(p);  write_insert_poll_safe();}voidPeerConnectionBase::read_cancel_piece(const Piece& p) {  PeerChunks::piece_list_type::iterator itr = std::find(m_peerChunks.upload_queue()->begin(), m_peerChunks.upload_queue()->end(), p);    if (itr != m_peerChunks.upload_queue()->end())    m_peerChunks.upload_queue()->erase(itr);}  voidPeerConnectionBase::read_buffer_move_unused() {  uint32_t remaining = m_down->buffer()->remaining();    std::memmove(m_down->buffer()->begin(), m_down->buffer()->position(), remaining);    m_down->buffer()->reset_position();  m_down->buffer()->set_end(remaining);}voidPeerConnectionBase::write_prepare_piece() {  m_upPiece = m_peerChunks.upload_queue()->front();  m_peerChunks.upload_queue()->pop_front();  // Move these checks somewhere else?  if (!m_download->content()->is_valid_piece(m_upPiece) ||      !m_download->content()->has_chunk(m_upPiece.index())) {    std::stringstream s;    s << "Peer requested a piece with invalid index or length/offset: "      << m_upPiece.index() << ' '      << m_upPiece.length() << ' '      << m_upPiece.offset();    throw communication_error(s.str());//     throw communication_error("Peer requested a piece with invalid index or length/offset.");  }        m_up->write_piece(m_upPiece);}// High stall count peers should request if we're *not* in endgame, or// if we're in endgame and the download is too slow. Prefere not to request// from high stall counts when we are doing decent speeds.boolPeerConnectionBase::should_request() {  if (m_down->choked() || !m_up->interested())    // || m_down->get_state() == ProtocolRead::READ_SKIP_PIECE)    return false;  else if (!m_download->delegator()->get_aggressive())    return true;  else    // We check if the peer is stalled, if it is not then we should    // request. If the peer is stalled then we only request if the    // download rate is below a certain value.    return m_downStall <= 1 || m_download->info()->down_rate()->rate() < (10 << 10);}boolPeerConnectionBase::try_request_pieces() {  if (download_queue()->empty())    m_downStall = 0;  uint32_t pipeSize = download_queue()->calculate_pipe_size(m_peerChunks.download_throttle()->rate()->rate());  // Don't start requesting if we can't do it in large enough chunks.  if (download_queue()->size() >= (pipeSize + 10) / 2)    return false;  bool success = false;  while (download_queue()->size() < pipeSize && m_up->can_write_request()) {    // Delegator should return a vector of pieces, and it should be    // passed the number of pieces it should delegate. Try to ensure    // it receives large enough request to fill a whole chunk if the    // peer is fast enough.    const Piece* p = download_queue()->delegate();    if (p == NULL)      break;    if (!m_download->content()->is_valid_piece(*p) || !m_peerChunks.bitfield()->get(p->index()))      throw internal_error("PeerConnectionBase::try_request_pieces() tried to use an invalid piece.");    m_up->write_request(*p);    success = true;  }  return success;}voidPeerConnectionBase::set_remote_interested() {  if (m_down->interested() || m_peerChunks.bitfield()->is_all_set())    return;  m_down->set_interested(true);  if (is_upload_wanted())    m_download->choke_manager()->set_interested(this);}voidPeerConnectionBase::set_remote_not_interested() {  if (!m_down->interested())    return;  bool wasUploadWanted = is_upload_wanted();  m_down->set_interested(false);  if (wasUploadWanted)    m_download->choke_manager()->set_not_interested(this);}}

⌨️ 快捷键说明

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