|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: Aug 2008
Città: Firenze
Messaggi: 317
|
[Python] Implementazione semplice Peer rete P2P
Salve,
Per un progetto universitario devo sviluppare un protocollo a livello applicativo che mi consenta di comunicare tra più peer in una rete locale. Il protocollo deve supportare due funzionalità che sono quelle di "discovery" e di "interact". Nella fase di discovery, basata su UDP, devo poter scovare i possibili partecipanti nella rete locale. Nella fase di interact, basata du TCP, devo poter comunicare con uno o più partecipanti. Sopra questo protocollo devo sviluppare una semplice chat. Ho pensato subito ad un archiettura P2P e quindi ho scritto una semplice classe cercando di implementare un peer. Posto il codice: Codice:
import socket
import sys
import threading
def debug_message(string):
print>>sys.stderr, "DEBUG MESSAGE: " + string
class Peer(object):
def __init__(self, port, host=None, ID=None, max_peers=0):
self.debug = True
self.max_peers = int(max_peers)
self.port = int(port)
if host:
self.host = host
else:
self.init_host()
if ID:
self.ID = ID
else:
self.ID = '%s:%s' % (self.host, self.port)
if self.debug:
debug_message(self.ID)
self.shutdown = False
self.peers = {}
self.handlers = {"FIND": self.discovery, "QUIT":
self.quit_peer, "PRNT": self.print_peers, "WHO": self.who, "SEND": self.send_message}
def init_host(self):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(("www.google.com", 80))
self.host = sock.getsockname()[0]
if self.debug:
debug_message(self.host)
sock.close()
def who(self):
print self.ID + ": (" + self.host + ":" + str(self.port) + ")"
def init_sock(self):
self.server_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.server_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.server_sock.bind(('', self.port))
self.clnt_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.clnt_sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
def discovery(self):
message = "ACK, %s" % (self.ID)
self.clnt_sock.sendto(message, ('<broadcast>', self.port))
def recive_message(self):
while True:
data, address = self.server_sock.recvfrom(1024)
print data
if data[:3] == 'ACK' and address not in self.peers:
self.peers[address] = data[5:]
#message = "ACK, %s" % (self.ID)
self.discovery()
def quit_peer(self):
self.shutdown = True
print "Exit"
def main_loop(self):
self.init_sock()
r = threading.Thread(target=self.recive_message, args=[])
r.daemon = True
r.start()
while not self.shutdown:
try:
self.msg = self.get_input()
command = self.msg[:4]
self.handle_peer(command)
except KeyboardInterrupt:
self.shutdown = True
continue
self.server_sock.close()
self.clnt_sock.close()
def handle_peer(self, command):
if command in self.handlers:
t = threading.Thread(target=self.handlers[command], args=[])
t.start()
t.join()
else:
print "no handler for this input"
def get_input(self):
print ">",
return raw_input()
def print_peers(self):
for address, ID in self.peers.items():
print address, ID
def send_message(self):
self.clnt_sock.sendto(self.msg[4:], ('<broadcast>', self.port))
if __name__ == '__main__':
if len(sys.argv) == 4:
p = Peer(port=sys.argv[1], ID=sys.argv[2], max_peers=sys.argv[3])
p.main_loop()
elif len(sys.argv) == 5:
p = Peer(port=sys.argv[1], host=sys.argv[2], ID=sys.argv[
3], max_peers=sys.argv[4])
p.main_loop()
1)Consigli generali su Python per migliorare il codice? 2)Come posso implementare la fase di discovery? Ho pensato di mandare un messaggio in broadcast a tutti e, se si trovano partecipanti, aggiungerli ad un dizionario tramite il loro indirizzo e il loro identificativo. Quando un Peer riceve un messaggio si salva il nome e l'indirizzo di chi l' ha mandato e risponde. Il problema è che se faccio partire due programmi e faccio una FIND in uno dei due il dizionario non contiene entrambi gli indirizzi. 3)L'approccio di fare broadcast per trovare i possibili partecipanti è giusto? 4)Mi rendo conto che la classe Peer dovrebbe essere indipendente dalle varie funzioni del protocollo. Come potrei separare l'implementazione del protocollo da quella del Peer? Aggiungo i metodi del protocollo dentro il dizionario in un secondo momento? Scusate per la poca chiarezza nella spiegazione. Ah, non posso usare Twisted o altro... Vi ringraziooooo Ultima modifica di Mulder90 : 29-01-2013 alle 14:55. Motivo: improve PEP8 |
|
|
|
|
|
#2 | ||||||
|
Senior Member
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26110
|
Quote:
Però è una cosa che puoi fare dopo, con comodo, quando il codice sarà funzionante. Quote:
Quote:
Quote:
Quindi il tuo codice funzionerebbe soltanto con IPv4. Ma potrebbe andare bene, per un esercizio. Quote:
Elenca un po' di requisiti, così verrà fuori il modello di Peer e di eventuali altre classi. Quote:
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro @LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys |
||||||
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 16:52.



















