From fdd214f20a035f7a3bca3c93ec80f89050c33a68 Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Wed, 10 Aug 2011 07:36:59 +0000 Subject: [PATCH] back-ported connection tester from aio-branch --- examples/connection_tester.cpp | 120 ++++++++++++++++++++++++++------- 1 file changed, 94 insertions(+), 26 deletions(-) diff --git a/examples/connection_tester.cpp b/examples/connection_tester.cpp index d49fa1248..4fd3b1c6d 100644 --- a/examples/connection_tester.cpp +++ b/examples/connection_tester.cpp @@ -342,13 +342,23 @@ struct peer_conn if (seed) { - if (msg == 6 && bytes_transferred == 13) + if (msg == 6) { + if (bytes_transferred != 13) + { + close("REQUEST packet has invalid size", error_code()); + return; + } int piece = detail::read_int32(ptr); int start = detail::read_int32(ptr); int length = detail::read_int32(ptr); write_piece(piece, start, length); } + else if (msg == 3) // not-interested + { + close("DONE", error_code()); + return; + } else { // read another message @@ -428,10 +438,14 @@ void print_usage() " this command takes two extra arguments:\n" " 1. the size of the torrent in megabytes\n" " 2. the file to save the .torrent file to\n\n" + " gen-data generate the data file(s) for the test torrent\n" + " this command takes two extra arguments:\n" + " 1. the torrent file that was previously generated\n" + " 2. the path to where the data should be stored\n" " upload start an uploader test\n" " download start a downloader test\n" " dual start a download and upload test\n" - " these commands set takes 4 additional arguments\n" + " these commands set takes 4 additional arguments:\n" " 1. num-connections - the number of connections to make to the target\n" " 2. destination-IP - the IP address of the target\n" " 3. destination-port - the port the target listens on\n" @@ -444,6 +458,24 @@ void print_usage() exit(1); } +void hasher_thread(libtorrent::create_torrent* t, int start_piece, int end_piece, int piece_size, bool print) +{ + if (print) fprintf(stderr, "\n"); + boost::uint32_t piece[0x4000 / 4]; + for (int i = start_piece; i < end_piece; ++i) + { + hasher ph; + for (int j = 0; j < piece_size; j += 0x4000) + { + generate_block(piece, i, j, 0x4000); + ph.update((char*)piece, 0x4000); + } + t->set_hash(i, ph.final()); + if (print && (i & 1)) fprintf(stderr, "\r%.1f %% ", float((i-start_piece) * 100) / float(end_piece-start_piece)); + } + if (print) fprintf(stderr, "\n"); +} + // size is in megabytes void generate_torrent(std::vector& buf, int size) { @@ -452,6 +484,7 @@ void generate_torrent(std::vector& buf, int size) const int piece_size = 1024 * 1024; const int num_pieces = size; const size_type total_size = size_type(piece_size) * num_pieces; +/* size_type s = total_size; int i = 0; while (s > 0) @@ -462,34 +495,49 @@ void generate_torrent(std::vector& buf, int size) fs.add_file(buf, (std::min)(s, size_type(20*1024*1024))); s -= 20*1024*1024; } +*/ + fs.add_file("stress_test_file", total_size); libtorrent::create_torrent t(fs, piece_size); - fprintf(stderr, "\n"); - boost::uint32_t piece[0x4000 / 4]; - for (int i = 0; i < num_pieces; ++i) - { - hasher ph; - for (int j = 0; j < piece_size; j += 0x4000) - { - generate_block(piece, i, j, 0x4000); - ph.update((char*)piece, 0x4000); - } - t.set_hash(i, ph.final()); - if (i & 1) fprintf(stderr, "\r%.1f %% ", float(i * 100) / float(num_pieces)); - } - fprintf(stderr, "\n"); + // generate the hashes in 4 threads + thread t1(boost::bind(&hasher_thread, &t, 0, 1 * num_pieces / 4, piece_size, false)); + thread t2(boost::bind(&hasher_thread, &t, 1 * num_pieces / 4, 2 * num_pieces / 4, piece_size, false)); + thread t3(boost::bind(&hasher_thread, &t, 2 * num_pieces / 4, 3 * num_pieces / 4, piece_size, false)); + thread t4(boost::bind(&hasher_thread, &t, 3 * num_pieces / 4, 4 * num_pieces / 4, piece_size, true)); + + t1.join(); + t2.join(); + t3.join(); + t4.join(); std::back_insert_iterator > out(buf); bencode(out, t.generate()); } +void generate_data(char const* path, int num_pieces, int piece_size) +{ + FILE* f = fopen(path, "w+"); + + boost::uint32_t piece[0x4000 / 4]; + for (int i = 0; i < num_pieces; ++i) + { + for (int j = 0; j < piece_size; j += 0x4000) + { + generate_block(piece, i, j, 0x4000); + fwrite(piece, 0x4000, 1, f); + } + if (i & 1) fprintf(stderr, "\r%.1f %% ", float(i * 100) / float(num_pieces)); + } + + fclose(f); +} + void io_thread(io_service* ios) { error_code ec; ios->run(ec); - if (ec) - fprintf(stderr, "ERROR: %s\n", ec.message().c_str()); + if (ec) fprintf(stderr, "ERROR: %s\n", ec.message().c_str()); } int main(int argc, char* argv[]) @@ -515,6 +563,18 @@ int main(int argc, char* argv[]) return 0; } + else if (strcmp(argv[1], "gen-torrent") == 0) + { + if (argc != 4) print_usage(); + error_code ec; + torrent_info ti(argv[2], ec); + if (ec) + { + fprintf(stderr, "ERROR LOADING .TORRENT: %s\n", ec.message().c_str()); + return 1; + } + generate_data(argv[3], ti.num_pieces(), ti.piece_length()); + } else if (strcmp(argv[1], "upload") == 0) { if (argc != 6) print_usage(); @@ -544,11 +604,15 @@ int main(int argc, char* argv[]) int port = atoi(argv[4]); tcp::endpoint ep(addr, port); +#if !defined __APPLE__ + // apparently darwin doesn't seems to let you bind to + // loopback on any other IP than 127.0.0.1 unsigned long ip = addr.to_ulong(); if ((ip & 0xff000000) == 0x7f000000) { local_bind = true; } +#endif torrent_info ti(argv[5], ec); if (ec) @@ -558,16 +622,17 @@ int main(int argc, char* argv[]) } std::list conns; - io_service ios; + const int num_threads = 2; + io_service ios[num_threads]; for (int i = 0; i < num_connections; ++i) { bool seed = false; if (test_mode == upload_test) seed = true; else if (test_mode == dual_test) seed = (i & 1); - conns.push_back(new peer_conn(ios, ti.num_pieces(), ti.piece_length() / 16 / 1024 + conns.push_back(new peer_conn(ios[i % num_threads], ti.num_pieces(), ti.piece_length() / 16 / 1024 , ep, (char const*)&ti.info_hash()[0], seed)); libtorrent::sleep(1); - ios.poll_one(ec); + ios[i % num_threads].poll_one(ec); if (ec) { fprintf(stderr, "ERROR: %s\n", ec.message().c_str()); @@ -576,8 +641,8 @@ int main(int argc, char* argv[]) } - thread t1(boost::bind(&io_thread, &ios)); - thread t2(boost::bind(&io_thread, &ios)); + thread t1(boost::bind(&io_thread, &ios[0])); + thread t2(boost::bind(&io_thread, &ios[1])); t1.join(); t2.join(); @@ -600,9 +665,12 @@ int main(int argc, char* argv[]) delete p; } - printf("=========================\ntotal sent: %.1f %% received: %.1f %%\n" - , total_sent * 0x4000 / float(ti.total_size()) - , total_received * 0x4000 / float(ti.total_size())); + printf("=========================\n" + "total sent: %.1f %% received: %.1f %%\n" + "rate sent: %.1f MB/s received: %.1f MB/s\n" + , total_sent * 0x4000 * 100.f / float(ti.total_size()) + , total_received * 0x4000 * 100.f / float(ti.total_size()) + , up, down); return 0; }