forked from premiere/premiere-libtorrent
*** empty log message ***
This commit is contained in:
parent
ec34b1bfdb
commit
1800e63c09
20
Jamfile
20
Jamfile
|
@ -26,13 +26,15 @@ lib torrent
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
#exe torrent_test
|
exe client_test
|
||||||
# : src/main.cpp <lib>torrent
|
: examples/client_test.cpp
|
||||||
# $(BOOST_ROOT)/libs/filesystem/build//boost_filesystem
|
<lib>torrent
|
||||||
# : <include>$(BOOST_ROOT)
|
# <lib>$(BOOST_ROOT)/libs/filesystem/build/boost_filesystem
|
||||||
# <sysinclude>$(BOOST_ROOT)
|
# <dll>$(BOOST_ROOT)/libs/thread/build/boost_thread
|
||||||
# <include>./
|
: <include>$(BOOST_ROOT)
|
||||||
# <threading>multi
|
<sysinclude>$(BOOST_ROOT)
|
||||||
# : debug release
|
<include>./include
|
||||||
# ;
|
<threading>multi
|
||||||
|
: debug release
|
||||||
|
;
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,19 @@
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<h1>libtorrent</h1>
|
<h1>libtorrent</h1>
|
||||||
|
|
||||||
|
<table style="margin-left:auto;margin-right:auto" cellpadding="10">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<a href="http://www.sourceforge.net/projects/libtorrent">sourceforge page</a>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a href="http://lists.sourceforge.net/lists/listinfo/libtorrent-discuss">mailing list</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
libtorrent is a C++ library that aims to be a good alternative to all the
|
libtorrent is a C++ library that aims to be a good alternative to all the
|
||||||
<a href="links.html">other bittorrent implementations</a> around. It is a
|
<a href="links.html">other bittorrent implementations</a> around. It is a
|
||||||
|
|
|
@ -150,6 +150,14 @@ namespace libtorrent
|
||||||
int index;
|
int index;
|
||||||
std::bitset<max_blocks_per_piece> requested_blocks;
|
std::bitset<max_blocks_per_piece> requested_blocks;
|
||||||
std::bitset<max_blocks_per_piece> finished_blocks;
|
std::bitset<max_blocks_per_piece> finished_blocks;
|
||||||
|
// TODO: store a hash and a peer_connection reference
|
||||||
|
// for each block. Then if the hash test fails on the
|
||||||
|
// piece, redownload one block from another peer
|
||||||
|
// then the first time, and check the hash again.
|
||||||
|
// also maintain a counter how many times a piece-hash
|
||||||
|
// has been confirmed. Download blocks that hasn't
|
||||||
|
// been confirmed (since they are most probably the
|
||||||
|
// invalid blocks)
|
||||||
};
|
};
|
||||||
|
|
||||||
struct has_index
|
struct has_index
|
||||||
|
@ -172,8 +180,12 @@ namespace libtorrent
|
||||||
// that no peer have, the vector at index 1 contains
|
// that no peer have, the vector at index 1 contains
|
||||||
// all pieces that exactly one peer have, index 2 contains
|
// all pieces that exactly one peer have, index 2 contains
|
||||||
// all pieces exactly two peers have and so on.
|
// all pieces exactly two peers have and so on.
|
||||||
|
|
||||||
std::vector<std::vector<int> > m_piece_info;
|
std::vector<std::vector<int> > m_piece_info;
|
||||||
|
|
||||||
|
// this vector has the same structure as m_piece_info
|
||||||
|
// but only contains pieces we are currently downloading
|
||||||
|
// they have higher priority than pieces we aren't downloading
|
||||||
|
// during piece picking
|
||||||
std::vector<std::vector<int> > m_downloading_piece_info;
|
std::vector<std::vector<int> > m_downloading_piece_info;
|
||||||
|
|
||||||
// this maps indices to number of peers that has this piece and
|
// this maps indices to number of peers that has this piece and
|
||||||
|
|
|
@ -72,9 +72,6 @@ namespace libtorrent
|
||||||
};
|
};
|
||||||
|
|
||||||
// wraps access to pieces with a file-like interface
|
// wraps access to pieces with a file-like interface
|
||||||
// TODO: add functionality for switching piece
|
|
||||||
// that's optimized not to closing the file if the
|
|
||||||
// new piece is in the same file
|
|
||||||
class piece_file
|
class piece_file
|
||||||
{
|
{
|
||||||
friend class storage;
|
friend class storage;
|
||||||
|
|
|
@ -61,7 +61,7 @@ namespace libtorrent
|
||||||
struct session_impl;
|
struct session_impl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: each torrent should have a status string that
|
// TODO: each torrent should have a status value that
|
||||||
// reflects what's happening to it
|
// reflects what's happening to it
|
||||||
// TODO: There should be a maximum number of peers that
|
// TODO: There should be a maximum number of peers that
|
||||||
// is maintained (if someone disconnects, try to connect to
|
// is maintained (if someone disconnects, try to connect to
|
||||||
|
@ -70,6 +70,7 @@ namespace libtorrent
|
||||||
// speed than one of the peers currently connected, it will be
|
// speed than one of the peers currently connected, it will be
|
||||||
// replaced to maximize bandwidth usage. It wil also have to
|
// replaced to maximize bandwidth usage. It wil also have to
|
||||||
// depend on how many and which pieces the peers have.
|
// depend on how many and which pieces the peers have.
|
||||||
|
// TODO: In debug mode all pieces that are sent should be checked.
|
||||||
|
|
||||||
|
|
||||||
// a torrent is a class that holds information
|
// a torrent is a class that holds information
|
||||||
|
@ -119,7 +120,8 @@ namespace libtorrent
|
||||||
int bytes_left() const { return m_storage.bytes_left(); }
|
int bytes_left() const { return m_storage.bytes_left(); }
|
||||||
|
|
||||||
// TODO: temporary implementation. Should count the actually
|
// TODO: temporary implementation. Should count the actually
|
||||||
// verified pieces
|
// verified pieces and should support the different states
|
||||||
|
// a torrent can be in.
|
||||||
float progress() const
|
float progress() const
|
||||||
{
|
{
|
||||||
return bytes_downloaded() / static_cast<float>(m_torrent_file.total_size());
|
return bytes_downloaded() / static_cast<float>(m_torrent_file.total_size());
|
||||||
|
@ -238,11 +240,13 @@ namespace libtorrent
|
||||||
// blocks when requested
|
// blocks when requested
|
||||||
int m_block_size;
|
int m_block_size;
|
||||||
|
|
||||||
|
// is set to true when the torrent has
|
||||||
|
// been aborted.
|
||||||
bool m_abort;
|
bool m_abort;
|
||||||
|
|
||||||
event_id m_event;
|
event_id m_event;
|
||||||
|
|
||||||
void parse_response(const entry& e);
|
void parse_response(const entry& e, std::vector<peer>& peer_list);
|
||||||
|
|
||||||
// total amount of bytes uploaded, downloaded and
|
// total amount of bytes uploaded, downloaded and
|
||||||
// the number of bytes left to be downloaded
|
// the number of bytes left to be downloaded
|
||||||
|
@ -266,9 +270,6 @@ namespace libtorrent
|
||||||
std::string m_failed;
|
std::string m_failed;
|
||||||
std::vector<peer_connection*> m_connections;
|
std::vector<peer_connection*> m_connections;
|
||||||
|
|
||||||
// TODO: move to a local function?
|
|
||||||
std::vector<peer> m_peer_list;
|
|
||||||
|
|
||||||
// -----------------------------
|
// -----------------------------
|
||||||
|
|
||||||
boost::shared_ptr<policy> m_policy;
|
boost::shared_ptr<policy> m_policy;
|
||||||
|
|
|
@ -402,9 +402,12 @@ bool libtorrent::peer_connection::dispatch_message()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// TODO: we have to let the piece_picker know that
|
// we have to let the piece_picker know that
|
||||||
// this piece failed the check os it can restore it
|
// this piece failed the check as it can restore it
|
||||||
// and mark it as being interesting for download
|
// and mark it as being interesting for download
|
||||||
|
// TODO: do this more intelligently! and keep track
|
||||||
|
// of how much crap (data that failed hash-check) and
|
||||||
|
// how much redundant data we have downloaded
|
||||||
picker.restore_piece(index);
|
picker.restore_piece(index);
|
||||||
}
|
}
|
||||||
m_torrent->get_policy().piece_finished(*this, index, verified);
|
m_torrent->get_policy().piece_finished(*this, index, verified);
|
||||||
|
@ -464,8 +467,6 @@ void libtorrent::peer_connection::request_block(piece_block block)
|
||||||
|
|
||||||
// TODO: add a timeout to disconnect peer if we don't get any piece messages when
|
// TODO: add a timeout to disconnect peer if we don't get any piece messages when
|
||||||
// we have requested.
|
// we have requested.
|
||||||
// TODO: there must be a way to ask the storage if a given
|
|
||||||
// piece already has some data (and how much). To avoid requesting
|
|
||||||
|
|
||||||
std::copy(buf, buf + 5, m_send_buffer.begin()+start_offset);
|
std::copy(buf, buf + 5, m_send_buffer.begin()+start_offset);
|
||||||
start_offset +=5;
|
start_offset +=5;
|
||||||
|
@ -685,6 +686,7 @@ void libtorrent::peer_connection::receive_data()
|
||||||
{
|
{
|
||||||
// verify peer_id
|
// verify peer_id
|
||||||
// TODO: It seems like the original client ignores to check the peer id
|
// TODO: It seems like the original client ignores to check the peer id
|
||||||
|
// can this be correct?
|
||||||
if (!std::equal(m_recv_buffer.begin(), m_recv_buffer.begin() + 20, (const char*)m_peer_id.begin()))
|
if (!std::equal(m_recv_buffer.begin(), m_recv_buffer.begin() + 20, (const char*)m_peer_id.begin()))
|
||||||
{
|
{
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
|
|
|
@ -90,7 +90,6 @@ namespace libtorrent
|
||||||
// TODO: random_shuffle
|
// TODO: random_shuffle
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: add a check to make sure m_downloads is intact
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
|
|
||||||
void piece_picker::integrity_check(const torrent* t) const
|
void piece_picker::integrity_check(const torrent* t) const
|
||||||
|
@ -304,6 +303,13 @@ namespace libtorrent
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: since inc_refcount is called
|
||||||
|
// with sequential indices when peers
|
||||||
|
// connect, it will sort the pieces
|
||||||
|
// that is not good. one solution is
|
||||||
|
// to insert the element at a random
|
||||||
|
// index when moving it to another
|
||||||
|
// vector.
|
||||||
bool piece_picker::inc_refcount(int i)
|
bool piece_picker::inc_refcount(int i)
|
||||||
{
|
{
|
||||||
assert(i >= 0);
|
assert(i >= 0);
|
||||||
|
@ -337,10 +343,6 @@ namespace libtorrent
|
||||||
|
|
||||||
if (index == 0xffffff) return;
|
if (index == 0xffffff) return;
|
||||||
move(m_piece_map[i].downloading, peer_count, index);
|
move(m_piece_map[i].downloading, peer_count, index);
|
||||||
|
|
||||||
#ifndef NDEBUG
|
|
||||||
integrity_check();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void piece_picker::we_have(int index)
|
void piece_picker::we_have(int index)
|
||||||
|
@ -360,10 +362,8 @@ namespace libtorrent
|
||||||
|
|
||||||
void piece_picker::pick_pieces(const std::vector<bool>& pieces, std::vector<piece_block>& interesting_pieces) const
|
void piece_picker::pick_pieces(const std::vector<bool>& pieces, std::vector<piece_block>& interesting_pieces) const
|
||||||
{
|
{
|
||||||
// TODO: modify this!
|
|
||||||
assert(pieces.size() == m_piece_map.size());
|
assert(pieces.size() == m_piece_map.size());
|
||||||
|
|
||||||
|
|
||||||
// free refers to pieces that are free to download, noone else
|
// free refers to pieces that are free to download, noone else
|
||||||
// is downloading them.
|
// is downloading them.
|
||||||
// partial is pieces that are partially being downloaded, and
|
// partial is pieces that are partially being downloaded, and
|
||||||
|
|
|
@ -71,9 +71,8 @@ namespace
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO:
|
// TODO: compare this peer's bandwidth against the
|
||||||
// compare this peer's bandwidth against the ones downloading
|
// ones downloading these pieces (busy_pieces)
|
||||||
// these pieces (busy_pieces)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -82,8 +82,9 @@ namespace
|
||||||
{
|
{
|
||||||
peer_id ret;
|
peer_id ret;
|
||||||
std::srand(std::time(0));
|
std::srand(std::time(0));
|
||||||
// unsigned char fingerprint[] = "h\0\0\0\0\0\0\0\0\0";
|
// TODO: add ability to control fingerprint
|
||||||
unsigned char fingerprint[] = "h\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
|
// unsigned char fingerprint[] = "lt.\0\0\0\0\0\0\0";
|
||||||
|
unsigned char fingerprint[] = "lt.\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
|
||||||
const int len = sizeof(fingerprint)-1;
|
const int len = sizeof(fingerprint)-1;
|
||||||
std::copy(fingerprint, fingerprint+len, ret.begin());
|
std::copy(fingerprint, fingerprint+len, ret.begin());
|
||||||
for (unsigned char* i = ret.begin()+len; i != ret.end(); ++i) *i = rand();
|
for (unsigned char* i = ret.begin()+len; i != ret.end(); ++i) *i = rand();
|
||||||
|
@ -181,7 +182,9 @@ namespace libtorrent
|
||||||
// that has been closed. Otherwise we have to wait 2 minutes for their timeout
|
// that has been closed. Otherwise we have to wait 2 minutes for their timeout
|
||||||
|
|
||||||
// let the readable clients receive data
|
// let the readable clients receive data
|
||||||
for (std::vector<boost::shared_ptr<socket> >::iterator i = readable_clients.begin(); i != readable_clients.end(); ++i)
|
for (std::vector<boost::shared_ptr<socket> >::iterator i = readable_clients.begin();
|
||||||
|
i != readable_clients.end();
|
||||||
|
++i)
|
||||||
{
|
{
|
||||||
|
|
||||||
// special case for listener socket
|
// special case for listener socket
|
||||||
|
@ -236,7 +239,9 @@ namespace libtorrent
|
||||||
// ************************
|
// ************************
|
||||||
|
|
||||||
// let the writable clients send data
|
// let the writable clients send data
|
||||||
for (std::vector<boost::shared_ptr<socket> >::iterator i = writable_clients.begin(); i != writable_clients.end(); ++i)
|
for (std::vector<boost::shared_ptr<socket> >::iterator i = writable_clients.begin();
|
||||||
|
i != writable_clients.end();
|
||||||
|
++i)
|
||||||
{
|
{
|
||||||
connection_map::iterator p = m_connections.find(*i);
|
connection_map::iterator p = m_connections.find(*i);
|
||||||
// the connection may have been disconnected in the receive phase
|
// the connection may have been disconnected in the receive phase
|
||||||
|
@ -269,7 +274,9 @@ namespace libtorrent
|
||||||
|
|
||||||
|
|
||||||
// disconnect the one we couldn't connect to
|
// disconnect the one we couldn't connect to
|
||||||
for (std::vector<boost::shared_ptr<socket> >::iterator i = error_clients.begin(); i != error_clients.end(); ++i)
|
for (std::vector<boost::shared_ptr<socket> >::iterator i = error_clients.begin();
|
||||||
|
i != error_clients.end();
|
||||||
|
++i)
|
||||||
{
|
{
|
||||||
connection_map::iterator p = m_connections.find(*i);
|
connection_map::iterator p = m_connections.find(*i);
|
||||||
|
|
||||||
|
@ -439,7 +446,7 @@ namespace libtorrent
|
||||||
boost::mutex::scoped_lock l(m_impl.m_mutex);
|
boost::mutex::scoped_lock l(m_impl.m_mutex);
|
||||||
|
|
||||||
// is the torrent already active?
|
// is the torrent already active?
|
||||||
// TODO: Maybe this should throw?
|
// TODO: this should throw
|
||||||
if (m_impl.m_torrents.find(ti.info_hash()) != m_impl.m_torrents.end())
|
if (m_impl.m_torrents.find(ti.info_hash()) != m_impl.m_torrents.end())
|
||||||
return torrent_handle(&m_impl, ti.info_hash());
|
return torrent_handle(&m_impl, ti.info_hash());
|
||||||
|
|
||||||
|
|
107
src/torrent.cpp
107
src/torrent.cpp
|
@ -71,7 +71,7 @@ namespace
|
||||||
|
|
||||||
int calculate_block_size(const torrent_info& i)
|
int calculate_block_size(const torrent_info& i)
|
||||||
{
|
{
|
||||||
// TODO: if blocks_per_piece > 64 increase block-size
|
// TODO: if blocks_per_piece > 128 increase block-size
|
||||||
return 16*1024;
|
return 16*1024;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,10 +154,63 @@ namespace libtorrent
|
||||||
|
|
||||||
void torrent::tracker_response(const entry& e)
|
void torrent::tracker_response(const entry& e)
|
||||||
{
|
{
|
||||||
|
std::vector<peer> peer_list;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// parse the response
|
// parse the response
|
||||||
parse_response(e);
|
parse_response(e, peer_list);
|
||||||
|
|
||||||
|
m_last_working_tracker
|
||||||
|
= m_torrent_file.prioritize_tracker(m_currently_trying_tracker);
|
||||||
|
m_next_request = boost::posix_time::second_clock::local_time()
|
||||||
|
+ boost::posix_time::seconds(m_duration);
|
||||||
|
m_currently_trying_tracker = 0;
|
||||||
|
|
||||||
|
// connect to random peers from the list
|
||||||
|
std::random_shuffle(peer_list.begin(), peer_list.end());
|
||||||
|
|
||||||
|
std::cout << "interval: " << m_duration << "\n";
|
||||||
|
std::cout << "peers:\n";
|
||||||
|
for (std::vector<peer>::const_iterator i = peer_list.begin();
|
||||||
|
i != peer_list.end();
|
||||||
|
++i)
|
||||||
|
{
|
||||||
|
std::cout << " " << std::setfill(' ') << std::setw(16) << i->ip
|
||||||
|
<< " " << std::setw(5) << std::dec << i->port << " ";
|
||||||
|
for (const unsigned char* j = i->id.begin();
|
||||||
|
j != i->id.end();
|
||||||
|
++j)
|
||||||
|
{
|
||||||
|
std::cout << std::hex << std::setw(2) << std::setfill('0')
|
||||||
|
<< static_cast<unsigned int>(*j);
|
||||||
|
}
|
||||||
|
std::cout << "\n";
|
||||||
|
}
|
||||||
|
std::cout << std::dec << std::setfill(' ');
|
||||||
|
|
||||||
|
|
||||||
|
// for each of the peers we got from the tracker
|
||||||
|
for (std::vector<peer>::iterator i = peer_list.begin();
|
||||||
|
i != peer_list.end();
|
||||||
|
++i)
|
||||||
|
{
|
||||||
|
// don't make connections to ourself
|
||||||
|
if (i->id == m_ses->get_peer_id())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
address a(i->ip, i->port);
|
||||||
|
|
||||||
|
// if we aleady have a connection to the person, don't make another one
|
||||||
|
if (std::find_if(m_ses->m_connections.begin(),
|
||||||
|
m_ses->m_connections.end(),
|
||||||
|
find_peer(i->id, this)) != m_ses->m_connections.end())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_policy->peer_from_tracker(a, i->id);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
catch(type_error& e)
|
catch(type_error& e)
|
||||||
{
|
{
|
||||||
|
@ -168,30 +221,6 @@ namespace libtorrent
|
||||||
tracker_request_error(e.what());
|
tracker_request_error(e.what());
|
||||||
}
|
}
|
||||||
|
|
||||||
m_last_working_tracker = m_torrent_file.prioritize_tracker(m_currently_trying_tracker);
|
|
||||||
m_next_request = boost::posix_time::second_clock::local_time() + boost::posix_time::seconds(m_duration);
|
|
||||||
m_currently_trying_tracker = 0;
|
|
||||||
|
|
||||||
// connect to random peers from the list
|
|
||||||
std::random_shuffle(m_peer_list.begin(), m_peer_list.end());
|
|
||||||
|
|
||||||
print(std::cout);
|
|
||||||
|
|
||||||
// for each of the peers we got from the tracker
|
|
||||||
for (std::vector<peer>::iterator i = m_peer_list.begin(); i != m_peer_list.end(); ++i)
|
|
||||||
{
|
|
||||||
// don't make connections to ourself
|
|
||||||
if (i->id == m_ses->get_peer_id())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
address a(i->ip, i->port);
|
|
||||||
|
|
||||||
// if we aleady have a connection to the person, don't make another one
|
|
||||||
if (std::find_if(m_ses->m_connections.begin(), m_ses->m_connections.end(), find_peer(i->id, this)) != m_ses->m_connections.end())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
m_policy->peer_from_tracker(a, i->id);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int torrent::num_connections(const peer_id& id) const
|
int torrent::num_connections(const peer_id& id) const
|
||||||
|
@ -223,7 +252,6 @@ namespace libtorrent
|
||||||
m_next_request = boost::posix_time::second_clock::local_time() + boost::posix_time::seconds(m_duration);
|
m_next_request = boost::posix_time::second_clock::local_time() + boost::posix_time::seconds(m_duration);
|
||||||
|
|
||||||
std::vector<char> buffer;
|
std::vector<char> buffer;
|
||||||
// TODO: temporary! support multi-tracker
|
|
||||||
std::string request = m_torrent_file.trackers()[m_currently_trying_tracker].url;
|
std::string request = m_torrent_file.trackers()[m_currently_trying_tracker].url;
|
||||||
|
|
||||||
request += "?info_hash=";
|
request += "?info_hash=";
|
||||||
|
@ -255,7 +283,7 @@ namespace libtorrent
|
||||||
return request;
|
return request;
|
||||||
}
|
}
|
||||||
|
|
||||||
void torrent::parse_response(const entry& e)
|
void torrent::parse_response(const entry& e, std::vector<peer>& peer_list)
|
||||||
{
|
{
|
||||||
entry::dictionary_type::const_iterator i = e.dict().find("failure reason");
|
entry::dictionary_type::const_iterator i = e.dict().find("failure reason");
|
||||||
if (i != e.dict().end())
|
if (i != e.dict().end())
|
||||||
|
@ -272,15 +300,14 @@ namespace libtorrent
|
||||||
i = msg.find("peers");
|
i = msg.find("peers");
|
||||||
if (i == msg.end()) throw std::runtime_error("invalid response from tracker");
|
if (i == msg.end()) throw std::runtime_error("invalid response from tracker");
|
||||||
|
|
||||||
m_peer_list.clear();
|
peer_list.clear();
|
||||||
|
|
||||||
const entry::list_type& peer_list = i->second.list();
|
const entry::list_type& l = i->second.list();
|
||||||
for(entry::list_type::const_iterator i = peer_list.begin(); i != peer_list.end(); ++i)
|
for(entry::list_type::const_iterator i = l.begin(); i != l.end(); ++i)
|
||||||
{
|
{
|
||||||
peer p = extract_peer_info(*i);
|
peer p = extract_peer_info(*i);
|
||||||
m_peer_list.push_back(p);
|
peer_list.push_back(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void torrent::remove_peer(peer_connection* p)
|
void torrent::remove_peer(peer_connection* p)
|
||||||
|
@ -328,20 +355,6 @@ namespace libtorrent
|
||||||
std::cout << "connecting to: " << a.as_string() << ":" << a.port() << "\n";
|
std::cout << "connecting to: " << a.as_string() << ":" << a.port() << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void torrent::print(std::ostream& os) const
|
|
||||||
{
|
|
||||||
os << "interval: " << m_duration << "\n";
|
|
||||||
os << "peers:\n";
|
|
||||||
for (std::vector<peer>::const_iterator i = m_peer_list.begin(); i != m_peer_list.end(); ++i)
|
|
||||||
{
|
|
||||||
os << " " << std::setfill(' ') << std::setw(16) << i->ip << " " << std::setw(5) << std::dec << i->port << " ";
|
|
||||||
for (const unsigned char* j = i->id.begin(); j != i->id.end(); ++j)
|
|
||||||
os << std::hex << std::setw(2) << std::setfill('0') << static_cast<unsigned int>(*j);
|
|
||||||
os << "\n";
|
|
||||||
}
|
|
||||||
os << std::dec << std::setfill(' ');
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
logger* torrent::spawn_logger(const char* title)
|
logger* torrent::spawn_logger(const char* title)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue