class Tracker(object): def __init__(self, port=DEFAULT_TRACKER_PORT): self.peers = [] self.current_port = FIRST_PORT self.logger = Logger() self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.server.bind((SOCKET_LISTENER_IP, port)) self.server.listen(5) self.running = True self.logger.log(u'Tracker aberto na porta {0}'.format(port)) self.logger.add_level() def add_peer(self, client, address): peer = (address[0], self.current_port) self.current_port += 1 if self.peers: client.send(json.dumps((peer, self.peers[0]))) else: client.send(json.dumps((peer, peer))) self.logger.log(u'Peer adicionado: {0}'.format(pretty_address(peer))) if len(self.peers) > 0: self.logger.log(u'Enviando endereço do peer {0} para o peer {1}'.format(pretty_address(peer), pretty_address(self.peers[-1]))) self.send_next_address(self.peers[-1], peer) self.peers.append(peer) self.logger.log(u'{0} peer(s)'.format(len(self.peers))) def remove_peer(self, peer): self.logger.log(u'Removendo peer: {0}'.format(peer)) if len(self.peers) > 1: index = self.peers.index(peer) previous_peer = self.peers[index - 1] next_peer = self.peers[(index + 1) % len(self.peers)] self.logger.log(u'Enviando endereço do peer {0} para o peer {1}'.format(pretty_address(next_peer), pretty_address(previous_peer))) self.send_next_address(previous_peer, next_peer) self.peers.pop(index) else: self.peers = [] self.logger.log(u'{0} peer(s)'.format(len(self.peers))) def send_next_address(self, peer, next): client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client.connect(peer) client.send(json.dumps({u'op': u'next', u'next': next})) client.close() def loop(self): while self.running: client, address = self.server.accept() self.logger.log(u'Peer conectado no endereço {0}'.format(pretty_address(address))) msg = json.loads(client.recv(1024)) if msg[u'op'] == u'add': self.add_peer(client, address) elif msg[u'op'] == u'remove': self.remove_peer(tuple(msg[u'peer'])) client.close() def close(self): self.logger.ident = 0 if CLOSE_PEERS: self.logger.log(u'Fechando Peers') for peer in self.peers: self.logger.log(u'Fechando peer: {0}'.format(pretty_address(peer))) client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client.connect(peer) client.send(json.dumps({u'op': u'close'})) client.close() self.logger.log(u'Fechando Tracker') self.running = False self.server.close()
class TrackerPeer(object): def __init__(self, tracker_ip='127.0.0.1', tracker_port=DEFAULT_TRACKER_PORT): self.this = None self.next = None self.tracker_ip = tracker_ip self.tracker_port = tracker_port self.logger = Logger() with Client((self.tracker_ip, self.tracker_port), name=u'Tracker', logger=self.logger) as client: client.send(json.dumps({u'op': u'add'})) self.this, self.next = json.loads(client.recv(1024)) self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.server.bind((SOCKET_LISTENER_IP, self.this[1])) self.server.listen(5) self.listeners = { u'close': self.receive_close, u'next': self.receive_next, } self.running = True self.logger.log(u'Servidor do Peer aberto em {0}'.format(pretty_address((socket.gethostbyname(socket.gethostname()), self.this[1])))) self.logger.add_level() def send_message_to_tracker(self, message): send_message((self.tracker_ip, self.tracker_port), message, name=u'Tracker', logger=self.logger) def send_message_to_next(self, message): send_message(self.next, message, name=u'Próximo', logger=self.logger) def info_print(self): self.logger.log(u'Endereço: {0}'.format(pretty_address(self.this))) self.logger.log(u'Próximo: {0}'.format(pretty_address(self.next))) def receive_close(self, msg): if CLOSE_PEERS: self.close(notify_tracker=False) def receive_next(self, msg): self.next = msg[u'next'] self.logger.log(u'Próximo peer alterado') self.info_print() def loop(self): while self.running: client, address = self.server.accept() self.logger.log(u'Peer conectado no endereço %s' % pretty_address(address)) self.logger.add_level() msg = json.loads(client.recv(1024)) self.logger.log(u'Operação "{0}"'.format(msg[u'op'])) self.listeners[msg[u'op']](msg) client.close() self.logger.log(u'Peer desconectado') self.logger.remove_level() def close(self, notify_tracker=True): self.logger.ident = 0 self.logger.log(u'Fechando Peer') if notify_tracker: self.send_message_to_tracker({ u'op': u'remove', u'peer': self.this }) self.close_extra(notify_tracker) self.running = False self.server.close()