搜片神器 之DHT网络爬虫的代码实现方法

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

               

 

 

继续接着第一篇写:使用C#实现DHT磁力搜索的BT种子后端管理程序+数据库设计(开源)[搜片神器]

 

 

 

开源地址:https://github.com/h31h31/H31DHTMgr

 

程序下载:H31DHT下载

 

 

 

看大家对昨天此类文章的兴趣没有第一篇高,今天就简单的对支持的朋友进行交流.园子里的朋友希望授大家以渔,所以这部分代码就先不放出来.希望大家更多的加入进来.

 

也希望谁有能力将C++的代码转换成C#的,添加到我们的搜片神器工具里面.

 

昨天通过向大家介绍DHT的工作原理,相信大家大概明白怎么回事,不明白的朋友可以继续分享接下来的文章.

 

 本人借鉴的代码是C++版本的:transmission里面的DHT代码,大家可以访问网站下载:http://www.transmissionbt.com/ 

 

不过里面的代码环境是LINUX下的,需要自己转换到相应的WIN平台上来.

 

有兴趣使用C#来完成DHT功能的朋友可以借鉴mono-monotorrent,里面的框架代码比较多,不如C++的transmission里面就三个文件来得明白.

 

 

transmission里面只有三个文件就可以实现dht的功能: dht.c dht.h dht-example.c,并且接口很简单,复用性很好。

 


下面介绍进入DHT网络主要功能步骤

dht.c dht.h代码分成三部分:
1、路由表的插入操作。
1)如果节点已经在路由表中,则更新节点,返回。
2)如果桶没有满,则插入,返回。
3)如果发现失效节点,替换,返回。
4)发现可疑节点,则保存新节点到缓存中并且如果该可疑节点没有ping,发出ping_node操作,返回。
5)现在,桶已经充满了好的节点,如果自己的ID没有落在这个桶中,返回。
6)将桶空间分成两半。跳到步骤1)。

2、KAD远程处理调用。
这部分又分成3种,
1)ping/pong操作。
所有的包的tid都使用pg\0\0
2)find_node操作。
所有的包的tid都使用fn\0\0
3)get_peers/annouce_peer操作。
对同一个HASH的一次递归查询中,tid保持不变。
其中只有3)种实现bittorrent的DHT规范里面提到的递归查询操作,1)和2)仅仅用来维护路由表,并且不保存状态。

3、定时器处理:
为了检测路由表中节点的有效性(根据规范,路由表中应该只保存有效节点),在代码中,在执行krpc操作时如果发现时对路由表中的节点操作,那么则保存操作的开始时间 pinged_time,通过操作的开始时间来判断操作是否超时。

expire_stuff_time 超时时,会执行下面的操作:
1、检查路由表中失效的节点(根据pinged_time来判定),并将该节点删除。
2、检查用来保存annoounce_peer的节点是否超过30分钟(这个不打算深入讨论,故不做解析)。
3、检查递归查询操作超时。

rotate_secrets_time 定时器。
用来每隔大约15分左右就更换token(见DHT规范).

confirm_nodes_time 定时器。
查找长期没有活动的桶,然后通过执行一个find_node的krpc操作来刷新它。

search_time定时器。
有可能出现发出的所有的get_peers操作,都没有应答,那么search_time定时器遇到这种情形时负责重发所有请求。(注意: get_peers操作最大未决的krpc请求数是3)

用于维持路由表的ping/pong操作:
在试图插入节点时,发现桶已经满,而存在可疑节点时会触发ping_node操作。未响应的节点会有可疑最终变为失效节点,而被替换。

下面介绍我们是如何进入DHT网络

 
  1. DHT必须把自己电脑当服务器,别人才能够知道自己是谁,所以需要通过UDP绑定端口,参考代码里面支持IPV6,个人觉得可以过滤掉.WIN平台代码如下:   
       
         
     1     //初始化socket 2     m_soListen =(int)socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); 3     if (m_soListen == INVALID_SOCKET) {
            4         m_iErrorNo=WSAGetLastError(); 5         _dout(_T("CH31CarMonitorDlg Start Error(%d).\n"),m_iErrorNo); 6         return -1; 7     } 8     //初始化服务器地址 9     SOCKADDR_IN addr;10     memset(&addr, 0, sizeof(addr));11     addr.sin_family = AF_INET;12     addr.sin_port = htons(port);13     addr.sin_addr.s_addr = htonl(INADDR_ANY);14     //绑定端口监听15     if (bind(m_soListen, (SOCKADDR*)&addr, sizeof(addr)) == SOCKET_ERROR) {
           16         m_iErrorNo=WSAGetLastError();17         _dout(_T("CH31CarMonitorDlg Start Error(%d).\n"),m_iErrorNo);18         return -2;19     }
        
         UDP端口绑定  
  2.   
  3. DHT需要生成一个自己的20位ID号,当然可以通过随机一个数值,然后通过SHA1来生成20位的ID号,WIN平台代码如下:   
       
         
    1 unsigned char p[20];2 CSHA1 sha1;3 sha1.Reset();4 sha1.Update((const unsigned char *)m_myID.GetBuffer(),   m_myID.GetLength());5 sha1.Final();6 sha1.GetHash(p);
        
         SHA1生成ID号  
  4.   
  5. 初始化他人服务器的IP信息,这样我们就可以从他们那里查询我们要的信息,借鉴代码如下:   
       
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值