def insert_peer(self, peer): # {{{ Splitter_DBS.insert_peer(self, peer) self.period[peer] = self.period_counter[peer] = 1 self.number_of_sent_chunks_per_peer[peer] = 0 #if __debug__: _p_("inserted", peer)
def send_chunk(self, chunk, peer): # {{{ Splitter_DBS.send_chunk(self, chunk, peer) try: self.number_of_sent_chunks_per_peer[peer] += 1 except KeyError: pass
def reset_counters(self): # {{{ Splitter_DBS.reset_counters(self) for i in self.period: #self.period[i] = ( self.period[i] + 1 ) / 2 self.period[i] -= 1 if self.period[i] < 1: self.period[i] = 1
def instance(self, args): if args.set_of_rules == "DBS" or args.set_of_rules == "IMS": Splitter_DBS.splitter_port = args.splitter_port Splitter_DBS.max_chunk_loss = args.max_chunk_loss Splitter_DBS.number_of_monitors = args.number_of_monitors Splitter_DBS.buffer_size = args.buffer_size self.splitter = Splitter_DBS("Splitter_DBS") if __debug__: lg = logging.getLogger("Splitter_DBS") lg.setLevel(args.loglevel)
def process_lost_chunk(self, lost_chunk_number, sender): # {{{ Splitter_DBS.process_lost_chunk(self, lost_chunk_number, sender) message = self.buffer[lost_chunk_number % self.BUFFER_SIZE] peer = self.peer_list[0] self.team_socket.sendto(message, peer) if __debug__: #sys.stdout.write(Color.cyan) _p_("Re-sending", lost_chunk_number, "to", peer)
def increment_unsupportivity_of_peer(self, peer): # {{{ Splitter_DBS.increment_unsupportivity_of_peer(self, peer) try: if peer != self.peer_list[0]: self.period[peer] += 1 self.period_counter[peer] = self.period[peer] except KeyError: pass
def remove_peer(self, peer): # {{{ Splitter_DBS.remove_peer(self, peer) try: del self.ids[peer] del self.port_steps[peer] del self.last_source_port[peer] except KeyError: pass
def __init__(self, buffer_size=32, max_chunk_loss=16, number_of_rounds=100, speed=4000, name="Splitter_DBS_simulator"): Splitter_DBS.__init__(self, buffer_size=buffer_size, max_chunk_loss=max_chunk_loss, name="Splitter_DBS_simulator") self.number_of_rounds = number_of_rounds self.speed = speed self.cpu_usage = 50 self.current_round = 0 self.packet_format() self.lg.debug("{name}: initialized") colorama.init()
def remove_peer(self, peer): # {{{ Splitter_DBS.remove_peer(self, peer) try: del self.period[peer] except KeyError: pass try: del self.period_counter[peer] except KeyError: pass try: del self.number_of_sent_chunks_per_peer[peer] except KeyError: pass
class Splitter(): def add_args(self, parser): parser.add_argument("-s", "--set_of_rules", default="IMS", help="Set of rules (default=\"IMS\")") parser.add_argument("-b", "--buffer_size", default=Splitter_DBS.buffer_size, type=int, help="Buffer size (default={})".format( Splitter_DBS.buffer_size)) parser.add_argument("-p", "--splitter_port", default=Splitter_DBS.splitter_port, type=int, help="Splitter port (default={})".format( Splitter_DBS.splitter_port)) parser.add_argument( "-l", "--max_chunk_loss", default=Splitter_DBS.max_chunk_loss, help="Maximum number of lost chunks per round (default={})".format( Splitter_DBS.max_chunk_loss)) parser.add_argument("-n", "--number_of_monitors", default=Splitter_DBS.number_of_monitors, help="Number of monitors (default={})".format( Splitter_DBS.number_of_monitors)) if __debug__: parser.add_argument("--loglevel", default=logging.ERROR, help="Log level (default={})".format( logging.getLevelName(logging.ERROR))) logging.basicConfig( format='%(asctime)s - %(name)s - %(levelname)s - %(message)s') def instance(self, args): if args.set_of_rules == "DBS" or args.set_of_rules == "IMS": Splitter_DBS.splitter_port = int(args.splitter_port) Splitter_DBS.max_chunk_loss = int(args.max_chunk_loss) Splitter_DBS.number_of_monitors = int(args.number_of_monitors) Splitter_DBS.buffer_size = int(args.buffer_size) self.splitter = Splitter_DBS("Splitter_DBS") if __debug__: lg = logging.getLogger("Splitter_DBS") lg.setLevel(args.loglevel) def run(self, args): self.splitter.setup_peer_connection_socket(port=args.splitter_port) self.splitter.setup_team_socket() self.splitter_address = self.splitter.get_id() self.splitter.run()
def run_a_splitter(self): Common.BUFFER_SIZE = self.get_buffer_size() if self.set_of_rules == "dbs": splitter = Splitter_DBS() elif self.set_of_rules == "cis": splitter = Splitter_STRPEDS() elif self.set_of_rules == "cis-sss": splitter = Splitter_SSS() #splitter.start() splitter.run()
import argparse import logging from core.splitter_dbs import Splitter_DBS from core.common import Common if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument("-s", "--set-of-rules", help="set of rules") parser.add_argument("-b", "--buffer-size", type=int, help="Buffer size") args = parser.parse_args() logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s') Common.BUFFER_SIZE = args.buffer_size if args.set_of_rules == "dbs": splitter = Splitter_DBS() # elif self.set_of_rules == "ims": # splitter = Splitter_IMS() splitter.setup_peer_connection_socket() splitter.setup_team_socket() splitter_address = splitter.get_id() print("Splitter Address: {}".format(splitter_address)) splitter.run()
def send_chunk(self, message, peer): # {{{ Splitter_DBS.send_chunk(self, message, peer) self.buffer[self.chunk_number % self.BUFFER_SIZE] = message
def run_a_splitter(self, splitter_id): Common.CHUNK_CADENCE = self.chunk_cadence if self.buffer_size == 0: Common.BUFFER_SIZE = self.compute_buffer_size() else: Common.BUFFER_SIZE = self.buffer_size self.lg.debug("(definitive) buffer_size={}".format(Common.BUFFER_SIZE)) if self.set_of_rules == "DBS" or self.set_of_rules == "IMS": splitter = Splitter_DBS() self.lg.info("simulator: DBS/IMS splitter created") elif self.set_of_rules == "CIS": splitter = Splitter_STRPEDS() self.lg.info("simulator: CIS splitter created") elif self.set_of_rules == "CIS-SSS": splitter = Splitter_SSS() self.lg.info("simulator: CIS-SSS splitter created") # splitter.start() splitter.setup_peer_connection_socket() splitter.setup_team_socket() splitter_id['address'] = splitter.get_id() splitter.max_number_of_rounds = self.number_of_rounds splitter.run()
def run_a_splitter(self, splitter_id): Common.BUFFER_SIZE = self.get_buffer_size() if self.set_of_rules == "dbs": splitter = Splitter_DBS() elif self.set_of_rules == "cis": splitter = Splitter_STRPEDS() elif self.set_of_rules == "cis-sss": splitter = Splitter_SSS() # splitter.start() splitter.setup_peer_connection_socket() splitter.setup_team_socket() splitter_id['address'] = splitter.get_id() splitter.run()
def __init__(self): # {{{ colorama.init() try: colorama.init() except Exception: pass # }}} # {{{ Running in debug/release mode _print_("Running in", end=' ') if __debug__: print("debug mode") else: print("release mode") # }}} # {{{ Arguments handling parser = argparse.ArgumentParser( description= 'This is the splitter node of a P2PSP team. The splitter is in charge of defining the Set or Rules (SoR) that will control the team. By default, DBS (unicast transmissions) will be used.' ) #parser.add_argument('--splitter_addr', help='IP address to serve (TCP) the peers. (Default = "{}")'.format(Splitter_IMS.SPLITTER_ADDR)) <- no ahora parser.add_argument( '--buffer_size', help='size of the video buffer in blocks. Default = {}.'.format( Splitter_IMS.BUFFER_SIZE)) parser.add_argument( '--channel', help= 'Name of the channel served by the streaming source. Default = "{}".' .format(Splitter_IMS.CHANNEL)) parser.add_argument('--chunk_size', help='Chunk size in bytes. Default = {}.'.format( Splitter_IMS.CHUNK_SIZE)) parser.add_argument( '--header_size', help='Size of the header of the stream in chunks. Default = {}.'. format(Splitter_IMS.HEADER_SIZE)) parser.add_argument( '--max_chunk_loss', help= 'Maximum number of lost chunks for an unsupportive peer. Makes sense only in unicast mode. Default = {}.' .format(Splitter_DBS.MAX_CHUNK_LOSS)) parser.add_argument( '--max_number_of_monitor_peers', help= 'Maxium number of monitors in the team. The first connecting peers will automatically become monitors. Default = "{}".' .format(Splitter_DBS.MONITOR_NUMBER)) parser.add_argument( '--mcast_addr', help= 'IP multicast address used to serve the chunks. Makes sense only in multicast mode. Default = "{}".' .format(Splitter_IMS.MCAST_ADDR)) parser.add_argument( '--port', help='Port to serve the peers. Default = "{}".'.format( Splitter_IMS.PORT)) parser.add_argument( '--source_addr', help= 'IP address or hostname of the streaming server. Default = "{}".'. format(Splitter_IMS.SOURCE_ADDR)) parser.add_argument( '--source_port', help='Port where the streaming server is listening. Default = {}.'. format(Splitter_IMS.SOURCE_PORT)) parser.add_argument( "--IMS", action="store_true", help= "Uses the IP multicast infrastructure, if available. IMS mode is incompatible with ACS, LRS, DIS and NTS modes." ) parser.add_argument("--NTS", action="store_true", help="Enables NAT traversal.") parser.add_argument("--ACS", action="store_true", help="Enables Adaptive Chunk-rate.") parser.add_argument("--LRS", action="store_true", help="Enables Lost chunk Recovery.") parser.add_argument("--DIS", action="store_true", help="Enables Data Integrity check.") parser.add_argument('--strpe', nargs='+', type=str, help='Selects STrPe model for DIS') parser.add_argument('--strpeds', nargs='+', type=str, help='Selects STrPe-DS model for DIS') parser.add_argument( '--strpeds_majority_decision', help='Sets majority decision ratio for STrPe-DS model.') parser.add_argument( '--strpe_log', help='Logging STrPe & STrPe-DS specific data to file.') parser.add_argument( '--TTL', help='Time To Live of the multicast messages. Default = {}.'. format(Splitter_IMS.TTL)) try: argcomplete.autocomplete(parser) except Exception: pass args = parser.parse_args() #args = parser.parse_known_args()[0] _print_("My IP address is =", socket.gethostbyname(socket.gethostname())) if args.buffer_size: Splitter_IMS.BUFFER_SIZE = int(args.buffer_size) _print_("Buffer size =", Splitter_IMS.BUFFER_SIZE) if args.channel: Splitter_IMS.CHANNEL = args.channel _print_("Channel = \"" + Splitter_IMS.CHANNEL + "\"") if args.chunk_size: Splitter_IMS.CHUNK_SIZE = int(args.chunk_size) _print_("Chunk size =", Splitter_IMS.CHUNK_SIZE) if args.header_size: Splitter_IMS.HEADER_SIZE = int(args.header_size) _print_("Header size =", Splitter_IMS.HEADER_SIZE) if args.port: Splitter_IMS.PORT = int(args.port) _print_("Listening port =", Splitter_IMS.PORT) if args.source_addr: Splitter_IMS.SOURCE_ADDR = socket.gethostbyname(args.source_addr) _print_("Source address = ", Splitter_IMS.SOURCE_ADDR) if args.source_port: Splitter_IMS.SOURCE_PORT = int(args.source_port) _print_("Source port =", Splitter_IMS.SOURCE_PORT) if args.IMS: _print_("IP multicast (IMS) mode selected") if args.mcast_addr: Splitter_IMS.MCAST_ADDR = args.mcast_addr _print_("Multicast address =", Splitter_IMS.MCAST_ADDR) if args.TTL: Splitter_IMS.TTL = args.TTL _print_("Multicast TTL =", Splitter_IMS.TTL) splitter = Splitter_IMS() splitter.peer_list = [] # No peer_list is used in IMS. else: _print_("IP unicast mode selected") if args.max_chunk_loss: Splitter_DBS.MAX_CHUNK_LOSS = int(args.max_chunk_loss) _print_("Maximun chunk loss =", Splitter_DBS.MAX_CHUNK_LOSS) if args.max_number_of_monitor_peers: Splitter_DBS.MONITOR_NUMBER = int( args.max_number_of_monitor_peers) _print_("Maximun number of monitor peers =", Splitter_DBS.MONITOR_NUMBER) splitter = Splitter_DBS() if args.NTS: splitter = Splitter_NTS(splitter) _print_("NTS enabled") if args.ACS: splitter = Splitter_ACS(splitter) _print_("ACS enabled") if args.LRS: from core.splitter_lrs import Splitter_LRS splitter = Splitter_LRS(splitter) _print_("LRS enabled") if args.DIS: from splitter_strpe import StrpeSplitter from splitter_strpeds import StrpeDsSplitter _print_("DIS enabled") if args.strpe: splitter = Splitter_strpe(splitter) print("strpe mode selected") for peer in args.strpe: splitter.add_trusted_peer(peer) if args.strpeds: splitter = StrpeSplitter(splitter) _print_("strpeds mode selected") for peer in args.strpeds: splitter.add_trusted_peer(peer) if args.strpeds_majority_decision: _print_("strpeds_majority_decision mode selected") splitter = Splitter_strpeds_majority_decision(splitter) splitter.setMajorityRatio( float(args.strpeds_majority_decision)) if args.strpe_log: splitter.LOGGING = True splitter.LOG_FILE = open(strpe_log, 'w', 0) #splitter = Splitter_ACS() # if (args.strpe): # splitter = self.init_strpe_splitter('strpe', args.strpe, args.strpe_log) # elif (args.strpeds): # splitter = self.init_strpe_splitter('strpeds', args.strpeds, args.strpe_log) # if args.strpeds_majority_decision: # splitter.setMajorityRatio(float(args.strpeds_majority_decision)) # else: # splitter = Splitter_LRS() # }}} # {{{ Run! splitter.start() # {{{ Prints information until keyboard interruption print(" | Received | Sent | Number losses/ losses") print( " Time | (kbps) | (kbps) | peers (peer) sents threshold period kbps" ) print( "---------+-----------+-----------+-----------------------------------..." ) last_sendto_counter = splitter.sendto_counter last_recvfrom_counter = splitter.recvfrom_counter while splitter.alive: try: time.sleep(1) chunks_sendto = splitter.sendto_counter - last_sendto_counter kbps_sendto = (chunks_sendto * splitter.CHUNK_SIZE * 8) / 1000 chunks_recvfrom = splitter.recvfrom_counter - last_recvfrom_counter kbps_recvfrom = (chunks_recvfrom * splitter.CHUNK_SIZE * 8) / 1000 last_sendto_counter = splitter.sendto_counter last_recvfrom_counter = splitter.recvfrom_counter sys.stdout.write(Color.none) _print_("|" + repr(int(kbps_recvfrom)).rjust(10) + " |" + repr(int(kbps_sendto)).rjust(10), end=" | ") #print('%5d' % splitter.chunk_number, end=' ') sys.stdout.write(Color.cyan) print(len(splitter.peer_list), end=' ') if not __debug__: counter = 0 for p in splitter.peer_list: if not __debug__: if counter > 10: break counter += 1 sys.stdout.write(Color.blue) print(p, end=' ') sys.stdout.write(Color.red) print(str('%3d' % splitter.losses[p]) + '/' + str('%3d' % chunks_sendto), splitter.MAX_CHUNK_LOSS, end=' ') if splitter is Splitter_ACS: try: sys.stdout.write(Color.yellow) print('%3d' % splitter.period[p], end=' ') sys.stdout.write(Color.purple) print(repr( (splitter.number_of_sent_chunks_per_peer[p] * splitter.CHUNK_SIZE * 8) / 1000).rjust(10), end=' ') splitter.number_of_sent_chunks_per_peer[p] = 0 except KeyError as e: print("!", e, "--") print(splitter.period[p]) pass sys.stdout.write(Color.none) print('', end=' ') print() except KeyboardInterrupt: print('Keyboard interrupt detected ... Exiting!') # Say to daemon threads that the work has been finished, splitter.alive = False # Wake up the "moderate_the_team" daemon, which is # waiting in a recvfrom(). if not args.IMS: #splitter.say_goodbye(("127.0.0.1", splitter.PORT), splitter.team_socket) splitter.team_socket.sendto(b'', ("127.0.0.1", splitter.PORT)) # Wake up the "handle_arrivals" daemon, which is waiting # in an accept(). sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect(("127.0.0.1", splitter.PORT)) sock.recv(struct.calcsize("4sH")) # Multicast channel sock.recv(struct.calcsize("H")) # Header size sock.recv(struct.calcsize("H")) # Chunk size sock.recv(splitter.CHUNK_SIZE * splitter.HEADER_SIZE) # Header sock.recv(struct.calcsize("H")) # Buffer size sock.recv(struct.calcsize("4sH")) # Endpoint sock.recv(struct.calcsize("B")) # Magic flags if args.IMS: number_of_peers = 0 else: number_of_peers = socket.ntohs( struct.unpack("H", sock.recv(struct.calcsize("H")))[0]) print("Number of peers =", number_of_peers) # Receive the list while number_of_peers > 0: sock.recv(struct.calcsize("4sH")) number_of_peers -= 1 # Breaks this thread and returns to the parent process # (usually, the shell). break
def __init__(self): Splitter_DBS.__init__(self) sys.stdout.write(Color.yellow) print("Using FNS") sys.stdout.write(Color.none)
def receive_chunk(self): # {{{ chunk = Splitter_DBS.receive_chunk(self) self.chunk_received_event.set() return chunk