ARIA2 Source Code Analysis-aria2.1.19.2 1.src/main.cc Main program entry, accept startup parameters from the command line, Judge system type, invoke different context constructors 2.context class/struct context (bool
standalone, int argc, char** argv, const keyvals& options);
Standalone/* does not understand the meaning of this variable, but the visual in OpenWrt is true, do not need to pay special attention to * * keyvals& options/*keyvals is a custom pointer, similar to the dictionary format, to the group.
The type of Key/value pairs.*/typedef STD::VECTOR<STD::p air<std::string, std::string> > keyvals;
3.context constructor implementation, first call the Option_processing function, basically is to parse the startup parameters, do not pay attention to the details. Then according to the protocol type call, judge whether BT is a URL or a magnetic link only analysis BT input parameter is local directory torrent file, not URL, so call Createrequestgroupforbittorrent 4.
Createrequestgroupforbittorrent/* This does a refactoring function, for the input is the URL of the torrent address or xxx.torrent file, in short, eventually converted to the seed file name * * But Adjustannounceuri didn't pass the value ...
And then continues to pass down as a parameter ... The Createbtrequestgroup 5.createBtRequestGroup/*adjustannounceuri is then invoked as the direct assignment to true in this function and is not clear why/auto RG = Std::make_
Shared<requestgroup> (GID, option);
Auto Dctx = std::make_shared<downloadcontext> (); /* This creates two class pointers to invoke its constructor/5.1 Requestgroup constructor initializes some download parameters, invokes two initialization functions, continues to drill down ... InitializepredownloadhaNdler ();
Initializepostdownloadhandler (); /* Initialize Download handle ... Get the BT download handle/Getbtpredownloadhandler,getbtpostdownloadhandler 5.2 downloadcontext Set Some download parameters, see naming should be for example, file size, fragmentation, such as 6. Missing before main.cc.
, the most important implementation of the program entry ...
if (context.reqinfo) {exitstatus = Context.reqinfo->execute ();
} std::shared_ptr<multiurlrequestinfo> Reqinfo;
/* Therefore, first call the excute*/7.error_code::value Multiurlrequestinfo::execute () try {e_->run () in Multiurlrequestinfo.
catch (recoverableexception& e) Here, E_ is std::unique_ptr<downloadengine> e_;
So next call the run 8.int Downloadengine::run (bool oneshot) in Downloadengine/* This cc run ()->excutecommand ()->excute () Here's the excute I think is bool Abstractcommand::execute () Here is the parent class (abstract class. Excute, according to the type of command, to determine which download mode to trigger the Excute () ...
Guess this is used in a series of constructor calls and initializations prior to Getdownloadengine, there are calls to their corresponding set macros//*abstractcommand::execute (), Excute of the base class, and all the other subclasses inherit * * 9.bool Abstractcommand::execute () Here is where to download the real implementation: E_->poolsocket (Req_, Createproxyrequest (), socket_); Downloadengine Poolsocket () This function downloads the socket thread pool.
Four morphological socketpoolentry E (sock, Std::move (timeout)) were reconstructed;
Poolsocket (Createsockpoolkey (ipaddr, Port, A2str::nil,proxyhost,proxyport), E);
10. To correct the Excute problem in 8, the original invocation form is as follows: for (size_t i = 0; i < max; ++i) {Auto com = Std::move (Commands.front ());
Commands.pop_front ();
if (!com->statusmatch (StatusFilter)) {com->clearioevents ();
Commands.push_back (Std::move (COM));
Continue
} com->transitstatus ();
if (Com->execute ()) {com.reset ();
else {com->clearioevents ();
Com.release (); }/*com is an automatic type, so the excute that is called here is exactly what the Excute in the class is looking at, so it is possible to call Excute in the base class Abstractcommand, or bool Fillrequestgroupcommand::execute () Correct the error. Abstractcommand is not a base class. The base class is the command ... Abstractcommand Downloadcommand Fillrequestgroupcommand and so on are all command's subclasses/11. Correct the previous error .... Abstractcommand..
This one, you should list a class inheritance diagram that starts with the command. But there are so many kinds ... Enumerate the Peerabstractcommand of the subclass Peerinitiateconnectioncommand bool Peerinitiateconnectioncommand::executeinternal () {a2_log_info (FMT msg_connecting_to_server, Getcuid (), Getpeer ()->getipaddress (). C_STR (), Getpeer ()->getport ())
;
Createsocket (); Getsocket ()->establishconnection (Getpeer ()->getipaddress (), Getpeer ()->getport
(), false);
This creates a socket connection ... 12. Continue to explore the subclass of the command base class and find that trackerwatchercommand this class should be a BT download to implement it in Excute if (!trackerrequest_) {trackerrequest_ = Createan
Nounce (e_)//Here is the creation of a client announcement message, which seems to be polling all the tracker information, each tracker server trying to connect. So here's the problem ...
Where is the seed resolution ...? 13. Seed parsing in the previously mentioned context constructor ...
All right, let's get this straight.
#ifdef enable_bittorrent if (!op->blank (pref_torrent_file)) {if (Op->get (pref_show_files) = = A2_v_true) {
Showtorrentfile (Op->get (pref_torrent_file));
Return else {createrequestgroupforbittorrent (requestgroups, op, args, Op->get p Ref_torrent_FILE)); }/* Yes.
This is the paragraph, blank is to determine whether the string is empty, here is the judge you give torrent file it. Op->get is the value of the parameter. Those macros are prefer pointers ... Some are numbers, some are strings, some are true or false in detail see prefers.cc is the attribute (preferance) definition ... Look at the general meaning of the file, should be put these different values, are categorized as pref pointers and then get an array of them all together, abstract as an ID, or a key value. The aria2 you call should give you the keyword or ID, and the program automatically converts to the meaning it represents .... This is probably the case//* to get to the point, here is the first to determine whether to provide the torrent file, and then determine what you want to do the operation. If it is a show-file operation, then parse the seed file and return the contents of the seed file ... What URI. Announce. Wait, I'll print it to you on the screen. If it is not show-file, then create the Requestgroup, where there is the resolution of the seed file. * * Show-file Branch, parse call is bittorrent::load () Createrequestgroup branch, call is Bittorent::loadfrommemory () they are all defined in Bittorent_
HELPER.CC read it carefully and found that both functions are called bittorent::p rocessrootdictionary () This function ... Here is the detailed analysis. Then, if the action is create, then the relevant information is stored to the two classes of Downloadcontext and Torrentattribute 14. Here I feel the approximate BT download framework is resolved. Can see aria2 with UDP hole (specific can see Nat traverse) to do peer-to-peer communication, and did not use ready-made BitTorrent library and so on, but the basic idea is to copy, namely Client-tracker-client mode 15. If you need to delve into a variety of features ... The best way I think is from the command this base class, find its subclasses ... Parse, tree-like traversal