Mulder90
29-01-2013, 10:26
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:
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()
I dubbi sono molti:
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 :D
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:
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()
I dubbi sono molti:
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 :D