zoukankan      html  css  js  c++  java
  • 电驴 emule 源代码分析 (1)

           关于电驴emule 的源代码,网上有一个  叫刘刚的人 分析的 非常多,可是假设你仅仅是看别人的分析,自己没有亲身去阅读代码的话,恐怕非常难  剖析整个系统。

         关于emule  主要就是 连接 kad网络部分, 搜索部分,共享部分,下载部分,还有就是IRC聊天部分。IRC聊天部分应该不是大多数人想知道的重点,核心部分  还是kad网络的构造 和 下载部分 的实现。 

         我看了下 搜索部分,大致的过程是下面酱紫。  希望有很多其它 学习emule源代码的人 一起交流共享。


          0. 连接到Kad网络的过程
         程序猿初始化 CemuleApp::InitInstance(), 会开启定时器。
         大致过程:
               uploadqueue = new CUploadQueue();-------------> SetTimer(0,0,TIMER_PERIOD,UploadTimer)-------------->theApp.emuledlg->PostMessage(TM_DOTIMER, NULL, NULL)
         --------------->CemuleDlg::DoTimer--------->CUploadQueue::UploadTimer.


         当点击  kad网络的  connectbutton后 ,调用   CKademlia::Start 函数, 
         m_bRunning  成员会被 置为 true.
         当定时器 读到这个标志为 true, 则运行 Kademlia::CKademlia::Process()函数。
         再调用  CRoutingZone::OnBigTimer  --->  CSearchManager::FindNode函数 -----> CSearchManager::StartSearch
         ----------->CSearch::Go()------->CSearch::SendFindValue->CKademliaUDPListener::SendPacket发出KADEMLIA2_REQ包。


        发KADEMLIA2_REQ包 的过程中,须要从列表中找到 近期的联系人。 
       


       

               1. 运行加入kad文件的过程。
         读取kad列表CRoutingZone::ReadFile
         从文件里读取 kad节点的 数据。




      2. 运行搜索的过程。
        
         (1)  CClientUDPSocket::SendPacket  把发送数据放入到队列中。
         整个具体过程是这样子:
             
            点击搜索button----> CSearchResultsWnd::StartSearch----->CSearchResultsWnd::StartNewSearch------>CSearchResultsWnd::DoNewKadSearch
         ------->Kademlia::CSearchManager::PrepareFindKeywords()------------->CSearch::Go()---->CSearch::SendFindValue----> CKademliaUDPListener::SendPacket
         ------->CClientUDPSocket::SendPacket----------->controlpacket_queue.AddTail.
          <===================================================================================================================================================
           这条数据包是 KADEMLIA2_REQ, 也就是说 对方会回复 KADEMLIA2_RES.当对方 回复KADEMLIA2_RES后  会依据是谁
          发的 KADEMLIA2_REQ来决定是否调用 CSearch::ProcessResponse, 将m_mapResponded加入值。
           于是当 以下的定时器轮询的时候if (m_mapResponded.count(itContactMap->first) > 0) 条件才会成立。接着调用CSearch::StorePacket
          <===================================================================================================================================================
            


         (2)  定时器轮询:
            CKademlia::Process()----->  CSearchManager::JumpStart()------->CSearch::JumpStart------>CSearch::StorePacket
        ----------------->CKademlia::GetUDPListener()->SendPacket(&m_pfileSearchTerms, KADEMLIA2_SEARCH_KEY_REQ, pFromContact->GetIPAddress(), pFromContact->GetUDPPort(), pFromContact->GetUDPKey(), &uClientID);
        ----------------->CClientUDPSocket::SendPacket----------->controlpacket_queue.AddTail.
         这个过程发出一个真真的搜索请求。
        
         (3) 处理搜索结果:
            CKademliaUDPListener::Process_KADEMLIA2_SEARCH_RES() ----> CSearch::ProcessResult() ------>  
          
          (4) 发送数据的过程
         开启线程 UploadBandwidthThrottler::RunInternal  ---> CClientUDPSocket::SendControlData  ---> CClientUDPSocket::SendTo ---->CAsyncSocket::SendTo
         真真的把数据发送出去。



           对于程序猿来说,“高手”和“菜鸟”之间的差别实际上仅仅有两个因素:一是从事编程时间的长短不同,使经验的多少有所差别;第二个因素就是手头掌握资料的多少了,由于非常多问题并非靠自己钻研能够解决的,必须靠资料,试想在写DOS汇编程序时假设没有中断手冊,能够自己钻研出来吗?实际上,大部分“菜鸟”向“高手”问的问题全然能够由參考资料解决,即使一个“菜鸟”对某个问题临时不懂,但手头有解决这个问题的具体资料,经过一段时间的钻研,问题自然会解决。“高手”就是这样慢慢练成的。

  • 相关阅读:
    RPC
    Memcache
    python supervisor使用
    代码规范
    值传递,引用传递
    日志文件目录
    input标签的事件汇总
    箭头函数
    JS数组reduce()方法
    关于Python变量的学习总结
  • 原文地址:https://www.cnblogs.com/blfshiye/p/4296951.html
Copyright © 2011-2022 走看看