def __handle_ping_request(self, msg, address): # 保存网络节点的ping请求,保存该结点信息 node = dht_bucket.Node(msg['a']['id'], *address) self.bucket.update(node.node_id, node) # 回复节点的Ping请求,以保持在线状态 data = {'t': msg['t'], 'y': 'r', 'r': {'id': self.server_id}} self.__send_message(data, address)
def decode_nodes(data): nodes = [] length = len(data) if length % 26 != 0: return nodes for idx in range(0, length, 26): nid = data[idx:idx + 20] nip = socket.inet_ntoa(data[idx + 20:idx + 24]) nport = struct.unpack('!H', data[idx + 24:idx + 26])[0] nodes.append(dht_bucket.Node(nid, nip, nport)) return nodes
def __handle_announce_request(self, msg, address): if 'implied_port' in msg['a'].keys() and msg['a']['implied_port'] != 0: port = address[1] else: port = msg['a']['port'] info = dht_store.SRC_INFO(dht_utils.id_to_hex(msg['a']['info_hash']), address[0], port, 1, int(time.time())) self.store.save(info) node = dht_bucket.Node(msg['a']['id'], *address) self.bucket.update(node.node_id, node)
def __handle_find_node_request(self, msg, address): # 保存发送消息的节点信息到路由表 node = dht_bucket.Node(msg['a']['id'], *address) self.bucket.update(node.node_id, node) # 获取k个与查询节点最近的节点信息作为应答 nodes = dht_utils.encode_nodes(self.bucket.get_kclose()) data = { 't': msg['t'], 'y': 'r', 'r': { 'id': self.server_id, 'nodes': nodes } } self.__send_message(data, address)
def __handle_response(self, msg, address): # 保存或更新消息发送方的信息到路由表 nid = msg['r']['id'] self.bucket.update(nid, dht_bucket.Node(nid, *address)) # 如果是Ping消息的应答,则应该删除该节点的ping请求超时设置 if msg['t'] != 'find_node': self.bucket.pop_tran(msg['t']) # 保存find_node应答消息中的nodes信息到路由表 if msg['r'].has_key('nodes'): nodes = dht_utils.decode_nodes(msg['r']['nodes']) for node in nodes: if node.node_id == self.server_id: continue self.bucket.update(node.node_id, node)
def __handle_get_peers_request(self, msg, address): # 接收到查询某个资源的请求,说明网络上可能存在该资源,因此保存该资源信息 info = dht_store.SRC_INFO(dht_utils.id_to_hex(msg['a']['info_hash']), address[0], address[1], 0, int(time.time())) self.store.save(info) # 更新或保存发送请求的节点信息 node = dht_bucket.Node(msg['a']['id'], *address) self.bucket.update(node.node_id, node) # 答复该节点的请求,以便下接收到announce_peer消息 nodes = dht_utils.encode_nodes(self.bucket.get_kclose()) data = { 't': msg['t'], 'y': 'r', 'r': { 'id': self.server_id, 'token': dht_utils.random_tranid(), 'nodes': nodes } } self.__send_message(data, address)