def __init__(self, bandwidth): SwitchPort.__init__(self, GlobalConfiguration.simpyEnv, float(bandwidth), None, False) self.bandwidth = bandwidth self.id = Interface.curr_id Interface.curr_id = Interface.curr_id + 1
def __init__(self, name, bandwidth, port, address, netmask): SwitchPort.__init__(self, GlobalConfiguration.simpyEnv, float(bandwidth), None, False) self.name = name self.bandwidth = bandwidth self.port = port self.address = address self.netmask = netmask
def __init__(self, id, env, gen): self.env = env self.id = id self.packet_generator = None self.gen = gen self.routes = {} self.routing_algorithm = None self.network = None self.env.process(self.run()) self.packet_sink = PacketSink(env=self.env, rec_arrivals=True) self.packets_to_send = simpy.Store(self.env, capacity=1) self.packets_forwarded = 0 self.packets_not_acknowledged = [] self.switch_port = SwitchPort(env=self.env, rate=20, qlimit=64, limit_bytes=False, id=self.id) self.switch_port.out = self.packets_to_send
def add_connection(self, dst_node, rate, qlimit, monitor_rate, propagation_delay, bidirectional=False): port_id = self.get_port_id(dst_node.id) new_port = SwitchPort(self.env, rate=rate, qlimit=qlimit, limit_bytes=False, id=port_id) self.output_ports[port_id] = new_port link_id = self.get_link_id(dst_node.id) new_link = Link(self.env, id=link_id, delay=propagation_delay, dst=dst_node, src=self.id, switch_port=new_port) self.routes[link_id] = new_link new_port.out = new_link def dist(gen, lbd): return gen.exponential(lbd) port_monitor_id = new_port.id dist_partial = partial(dist, self.gen, monitor_rate) port_monitor = PortMonitor(self.env, port=new_port, dist=dist_partial) self.port_monitors[port_monitor_id] = port_monitor if bidirectional: dst_node.add_connection(self, rate, qlimit, monitor_rate, propagation_delay)
# Create the packet generators and sink def selector(pkt): return pkt.src == "SJSU1" def selector2(pkt): return pkt.src == "SJSU2" ps1 = PacketSink(env, debug=False, rec_arrivals=True, selector=selector) ps2 = PacketSink(env, debug=False, rec_waits=True, selector=selector2) pg1 = PacketGenerator(env, "SJSU1", adist1, sdist) pg2 = PacketGenerator(env, "SJSU2", adist2, sdist) pg3 = PacketGenerator(env, "SJSU3", adist3, sdist) branch1 = RandomBrancher(env, [0.75, 0.25]) branch2 = RandomBrancher(env, [0.65, 0.35]) switch_port1 = SwitchPort(env, 's1', port_rate) switch_port2 = SwitchPort(env, 's2', port_rate) switch_port3 = SwitchPort(env, 's3', port_rate) switch_port4 = SwitchPort(env, 's4', port_rate) # Wire packet generators, switch ports, and sinks together pg1.out = switch_port1 switch_port1.out = branch1 branch1.outs[0] = switch_port2 switch_port2.out = branch2 branch2.outs[0] = switch_port3 branch2.outs[1] = switch_port4 pg3.out = switch_port3 pg2.out = switch_port4 switch_port3.out = ps1 switch_port4.out = ps2
# Create the packet generators and sink def selector(pkt): return pkt.src == "SJSU1" def selector2(pkt): return pkt.src == "SJSU2" ps1 = PacketSink(env, debug=False, rec_arrivals=True, selector=selector) ps2 = PacketSink(env, debug=False, rec_waits=True, selector=selector2) pg1 = PacketGenerator(env, "SJSU1", adist1, sdist) pg2 = PacketGenerator(env, "SJSU2", adist2, sdist) pg3 = PacketGenerator(env, "SJSU3", adist3, sdist) branch1 = RandomBrancher(env, [0.75, 0.25]) branch2 = RandomBrancher(env, [0.65, 0.35]) switch_port1 = SwitchPort(env, port_rate) switch_port2 = SwitchPort(env, port_rate) switch_port3 = SwitchPort(env, port_rate) switch_port4 = SwitchPort(env, port_rate) # Wire packet generators, switch ports, and sinks together pg1.out = switch_port1 switch_port1.out = branch1 branch1.outs[0] = switch_port2 switch_port2.out = branch2 branch2.outs[0] = switch_port3 branch2.outs[1] = switch_port4 pg3.out = switch_port3 pg2.out = switch_port4 switch_port3.out = ps1 switch_port4.out = ps2
if __name__ == '__main__': # Set up arrival and packet size distributions # Using Python functools to create callable functions for random variates with fixed parameters. # each call to these will produce a new random value. adist = functools.partial(random.expovariate, 0.5) sdist = functools.partial(random.expovariate, 0.01) # mean size 100 bytes samp_dist = functools.partial(random.expovariate, 1.0) port_rate = 1000.0 # Create the SimPy environment env = simpy.Environment() # Create the packet generators and sink ps = PacketSink(env, debug=False, rec_arrivals=True) pg = PacketGenerator(env, "Test", adist, sdist) switch_port = SwitchPort(env, port_rate, qlimit=10000) # Using a PortMonitor to track queue sizes over time pm = PortMonitor(env, switch_port, samp_dist) # Wire packet generators, switch ports, and sinks together pg.out = switch_port switch_port.out = ps # Run it env.run(until=8000) print("Last 10 waits: " + ", ".join(["{:.3f}".format(x) for x in ps.waits[-10:]])) print("Last 10 queue sizes: {}".format(pm.sizes[-10:])) print("Last 10 sink arrival times: " + ", ".join(["{:.3f}".format(x) for x in ps.arrivals[-10:]])) print("average wait = {:.3f}".format(sum(ps.waits) / len(ps.waits))) print("received: {}, dropped {}, sent {}".format(switch_port.packets_rec, switch_port.packets_drop,
def _create_switchport(self, rate, qlimit, outgoing_port_id): return SwitchPort(self.env, rate=rate, qlimit=qlimit, limit_bytes=False, id=outgoing_port_id)
import simpy from SimComponents import PacketGenerator, PacketSink, SwitchPort def constArrival(): return 1.5 # time interval def constSize(): return 100.0 # bytes env = simpy.Environment() # Create the SimPy environment ps = PacketSink(env, debug=True) # debug: every packet arrival is printed pg = PacketGenerator(env, "SJSU", constArrival, constSize) switch_port = SwitchPort(env, rate=200.0, qlimit=300) # Wire packet generators and sinks together pg.out = switch_port switch_port.out = ps env.run(until=20) print("waits: {}".format(ps.waits)) print("received: {}, dropped {}, sent {}".format(ps.packets_rec, switch_port.packets_drop, pg.packets_sent))
class Node(object): def __init__(self, id, env, gen): self.env = env self.id = id self.packet_generator = None self.gen = gen self.routes = {} self.routing_algorithm = None self.network = None self.env.process(self.run()) self.packet_sink = PacketSink(env=self.env, rec_arrivals=True) self.packets_to_send = simpy.Store(self.env, capacity=1) self.packets_forwarded = 0 self.packets_not_acknowledged = [] self.switch_port = SwitchPort(env=self.env, rate=20, qlimit=64, limit_bytes=False, id=self.id) self.switch_port.out = self.packets_to_send #self.port_monitor = PortMonitor(env, self.switch_port, dist=1) def set_network(self, network): """ Set the network in which the node is placed in :param network: network :return: None """ self.network = network return def set_routing_algorithm(self, controller="RL"): """Set routing algorithm for this node :param controller: :return: """ if controller == "random": self.routing_algorithm = RandomRouting(gen=self.gen, node=self, graph=self.network) elif controller == "dijkstra": self.routing_algorithm = Dijkstra(graph=self.network, node=self) elif controller == "RL": self.routing_algorithm = RLRouting(node=self, graph=self.network) else: pass def route(self, packet): """Query the rooting algorithm for a link to route the packet to :param packet: :return: """ return self.routing_algorithm.route_packet(packet) def set_packet_generator(self, lbd, possible_destinations): """ :param lbd: :param possible_destinations: :return: """ def dst_dist(gen, destinations): if destinations is None: return None else: return gen.choice(destinations) def next_packet_time(gen, lbd_): return gen.exponential(lbd_) packet_dst = partial(dst_dist, self.gen, possible_destinations) next_pkt_time = partial(next_packet_time, self.gen, lbd) self.packet_generator = PacketGenerator(env=self.env, id="{}_pg".format(self.id), adist=next_pkt_time, sdist=100, dstdist=packet_dst) ## LOOK AT THIS AGAIN - might want to consider putting it into a switch port self.packet_generator.out = self.packets_to_send def get_port_id(self, dst_node_id): return "{}_{}".format(self.id, dst_node_id) def get_link_id(self, dst_node): return "{}_{}".format(self.id, dst_node.id) def add_connection(self, dst_node, rate, qlimit, monitor_rate, propagation_delay, bidirectional=True): """Add a new connection to this node given the following set of parameters :param dst_node: :param rate: :param qlimit: :param monitor_rate: :param propagation_delay: :param bidirectional: :return: """ link_id = self.get_link_id(dst_node) new_link = Link(self.env, id=link_id, cost=propagation_delay, dst=dst_node, src=self) self.routes[link_id] = new_link if bidirectional: new_link_reverse = dst_node.add_connection(self, rate=rate, qlimit=qlimit, monitor_rate=monitor_rate, propagation_delay=propagation_delay, bidirectional=False) return [new_link, new_link_reverse[0]] return [new_link] def id_str_to_num(self): return int(self.id.strip("n")) def get_neighbours(self): """Get neighbours of this node :return: list of neighbouring nodes sorted by id """ neighbours = [] neighbour_debug = [] neighbour_id = self.get_neighbour_id() for name in neighbour_id: link_name = "{}_{}".format(self.id, name) neighbours.append(self.routes[link_name].dst) neighbour_debug.append(link_name) #print("debug " + str(neighbour_debug)) return neighbours def get_neighbour_id(self): """Get all id's of neighbours of this node :return: sorted list of of neighbour ids """ neighbour_id = [] for link in self.routes.values(): if link.src.id == self.id: neighbour = link.dst else: neighbour = link.src neighbour_id.append(neighbour.id) neighbour_id.sort() return neighbour_id def is_neighbour(self, node): """Check if a certain node is a neighbour of this node :param node: Node name (str) to be searched for among the neighbours :return: Boolean indicating if the node is found """ if node == self: return False for link in self.routes.values(): if link.dst == node or link.src == node: return True return False def get_link(self, node): return self.routes["{}_{}".format(self.id, node.id)] def clear_packets(self): """Clear all packets from the node's switch port :return: None """ while len(self.packets_to_send.items) is not 0: packet = self.packets_to_send.get() del packet self.switch_port.clear_packets() #del self.switch_port #self.switch_port = SwitchPort(env=self.env, rate=20, qlimit=64, limit_bytes=False, id=self.id) def send_acknowledgement(self, packet): pkt = AcknowledgementPacket(time=self.env.now, src=self.id, dst=packet.src, id=packet.id, size=1) print("creating ack packet with dst" + str(pkt.dst)) self.put(pkt) def put(self, packet): """Called by objects that wants to put a packet into this node :param packet: Packet object :return: None """ if not isinstance(packet, Packet): return previous_node = packet.current_node packet.set_current_node(self) if packet.dst == self.id: if isinstance(packet, AcknowledgementPacket): self.packets_not_acknowledged.remove("n{}".format(packet.acknowledgement_id.strip("ack"))) else: self.packet_sink.put(packet) # self.send_acknowledgement(packet) else: self.switch_port.put(packet) if packet.src == self.id: self.packets_not_acknowledged.append(packet.id) if previous_node is not None: print("Packet " + str(packet.id) + " put from node " + str(previous_node.id) + " into node " + str(self.id)) else: print("Packet " + str(packet.id) + " put into node " + str(self.id)) def run(self): """Simpy process: constantly runs and creates events that are put into the event queue :return: None """ while True: packet = yield (self.packets_to_send.get()) outgoing_port = self.route(packet) if outgoing_port is not None and self.routes[outgoing_port.id].state: packet.increment_hops() packet.incrementRouteWeight(self.routes[outgoing_port.id].cost) packet.total_traffic += self.routes[outgoing_port.id].traffic packet.decrement_ttl(self.env.now) packet.path.append([outgoing_port.dst.id, self.routes[outgoing_port.id].cost]) outgoing_port.put(packet) self.packets_forwarded += 1 elif outgoing_port is None: self.put(packet) else: pass
def selector2(pkt): return pkt.src == "SJSU2" def selector3(pkt): return pkt.src == "SJSU3" ps1 = PacketSink(env, debug=False, rec_arrivals=True, selector=selector) ps2 = PacketSink(env, debug=False, rec_waits=True, selector=selector2) ps3 = PacketSink(env, debug=False, rec_arrivals=True, selector=selector3) pg1 = PacketGenerator(env, "SJSU1", adist1, sdist) pg2 = PacketGenerator(env, "SJSU2", adist2, sdist) pg3 = PacketGenerator(env, "SJSU3", adist3, sdist) router = Router(env, 3) switch_port1 = SwitchPort(env, port_rate) switch_port2 = SwitchPort(env, port_rate) switch_port3 = SwitchPort(env, port_rate) switch_port4 = SwitchPort(env, port_rate) # Wire packet generators, switch ports, and sinks together pg1.out = switch_port1 pg2.out = switch_port1 pg3.out = switch_port1 switch_port1.out = router router.outs[0] = switch_port2 router.outs[1] = switch_port3 router.outs[2] = switch_port4 switch_port2.out = ps1 switch_port3.out = ps2
def MM1K(lamda, mu, ql, user, port_rate, Tsim, bins, directorio): try: plt.close('all') ############# DEFINICION DE LOS PARAMETROS DEL MODELO ######################### # Creacion de carpeta temporal para guardar graficos if os.path.exists(directorio + 'temp_graficos'): shutil.rmtree(directorio + 'temp_graficos') os.mkdir(directorio + 'temp_graficos') #Parametros del Sumidero debugSink = False #o False, muestra en la salida lo que llega al servidor rec_arrivalsSink = True #Si es verdadero los arribos se graban abs_arrivalsSink = False # true, se graban tiempos de arribo absoluto; False, el tiempo entre arribos consecutivos #Parametros del Generador de Paquetes. mu_paq = ((mu * 8) / port_rate) adist = functools.partial( random.expovariate, lamda) #Tiempo de inter arribo de los paquetes sdist = functools.partial(random.expovariate, mu_paq) # Tamaño de los paquetes #Parametros del Monitor Smd = lamda samp_dist = functools.partial(random.expovariate, Smd) ############################################################################### ############# CREACION DEL ENTORNO Y SUS COMPONENTES ######################### # Creación del Entorno de Simpy env = simpy.Environment() # Creación del Generador de Paquetes y Servidor psink = PacketSink(env, debug=debugSink, rec_arrivals=rec_arrivalsSink, absolute_arrivals=abs_arrivalsSink) pg = PacketGenerator(env, user, adist, sdist) switch_port = SwitchPort(env, rate=port_rate, qlimit=ql) # PortMonitor para rastrear los tamaños de cola a lo largo del tiempo pm = PortMonitor(env, switch_port, samp_dist, count_bytes=True) ############################################################################### ############# CONEXION DE LOS COMPONENTES DEL MODELO ######################### pg.out = switch_port switch_port.out = psink # Correr la simulacion del entorno. Paramatro el tiempo env.run(until=Tsim) ############################################################################### ############# MUESTRA DE RESULTADOS ########################################## pkt_drop = switch_port.packets_drop pkt_recibidos_serv = psink.packets_rec pkt_enviados = pg.packets_sent ocup_sistema_L = float(sum(pm.sizes)) / len(pm.sizes) intensidad_trafico = lamda / mu if lamda != mu: pk = (((1 - intensidad_trafico) * intensidad_trafico**(ql)) / (1 - intensidad_trafico**(ql + 1))) else: pk = 1 / (ql + 1) lamda_eficaz = lamda * (1 - pk) espera_sist_W = ocup_sistema_L / lamda_eficaz espera_cola_Wq = espera_sist_W - 1 / mu ocup_cola_Lq = espera_cola_Wq * lamda_eficaz tasa_perdida = lamda * pk ############################################################################### ############# GRAFICOS ####################################################### directorio = directorio + "temp_graficos/" #--------- NORMALIZADOS----------------------------------------------------- fig, axis = plt.subplots() axis.hist(psink.waits, bins, normed=True, alpha=1, edgecolor='black', linewidth=1) axis.set_title("Tiempos de Espera - Normalizado") axis.set_xlabel("Tiempo") axis.set_ylabel("Frecuencia de ocurrencia") fig.savefig(directorio + "WaitHistogram_normal.png") fig, axis = plt.subplots() axis.hist(pm.sizes, bins, normed=True, alpha=1, edgecolor='black', linewidth=1) axis.set_title("Tiempos de Ocupación del Sistema - Normalizado") axis.set_xlabel("Nro") axis.set_ylabel("Frecuencia de ocurrencia") fig.savefig(directorio + "QueueHistogram_normal.png") fig, axis = plt.subplots() axis.hist(psink.arrivals, bins, normed=True, alpha=1, edgecolor='black', linewidth=1) axis.set_title("Tiempos de Inter-Arribo a la Cola - Normalizado") axis.set_xlabel("Tiempo") axis.set_ylabel("Frecuencia de ocurrencia") fig.savefig(directorio + "ArrivalHistogram_normal.png") #---------SIN NORMALIZAR----------------------------------------------------- fig, axis = plt.subplots() axis.hist(psink.waits, bins, normed=False, alpha=1, edgecolor='black', linewidth=1) axis.set_title("Tiempos de Espera") axis.set_xlabel("Tiempo") axis.set_ylabel("Frecuencia de ocurrencia ") fig.savefig(directorio + "WaitHistogram.png") fig, axis = plt.subplots() axis.hist(pm.sizes, bins, normed=False, alpha=1, edgecolor='black', linewidth=1) axis.set_title("Tiempos de Ocupación del Sistema") axis.set_xlabel("Nro") axis.set_ylabel("Frecuencia de ocurrencia") fig.savefig(directorio + "QueueHistogram.png") fig, axis = plt.subplots() axis.hist(psink.arrivals, bins, normed=False, alpha=1, edgecolor='black', linewidth=1) axis.set_title("Tiempos de Inter-Arribo a la Cola") axis.set_xlabel("Tiempo") axis.set_ylabel("Frecuencia de ocurrencia") fig.savefig(directorio + "ArrivalHistogram.png") datos = psink.data str1 = '&'.join(datos) aux_str1 = str1 str1 = aux_str1.replace('&', '\n') aux_str1 = str1 str1 = (aux_str1.replace(',', ' \t ')) return str1, espera_sist_W, pkt_drop, pkt_enviados, tasa_perdida, ocup_sistema_L, pkt_recibidos_serv, intensidad_trafico, espera_cola_Wq, ocup_cola_Lq except: error = traceback.format_exc() QMessageBox.critical( None, 'Error de ejecucion', "Detalle del error:\n\n" + error + '\n\nPor favor, revise la documentacion del programa.', QMessageBox.Ok) sys.exit(0)
port_rate = 100 / 8 * 10**6 # 100Mbit/s qlim = 4 * 10**6 #4Mb # Create the SimPy environment. This is the thing that runs the simulation. env = simpy.Environment() ps1 = PacketSink(env, debug=False, rec_arrivals=True) # figure out the use of selector # ps1 = PacketSink(env, debug=False, rec_arrivals=True) pg1 = PacketGenerator(env, 'src1', adist1, sdist) pg2 = PacketGenerator(env, 'src2', adist2, sdist) branch1 = RandomBrancher(env, [0.50, 0.50]) branch2 = RandomBrancher(env, [0.50, 0.50]) #pseudoBrancher branch3 = RandomBrancher(env, [1.00, 0.00]) switch_port1 = SwitchPort(env, port_rate, qlimit=qlim) switch_port2 = SwitchPort(env, port_rate, qlimit=qlim) switch_port3 = SwitchPort(env, port_rate, qlimit=qlim) switch_port4 = SwitchPort(env, port_rate, qlimit=qlim) switch_port5 = SwitchPort(env, port_rate, qlimit=qlim) # Wire packet generators, switch ports, and sinks together pg1.out = switch_port1 switch_port1.out = branch1 branch1.outs[0] = switch_port3 branch1.outs[1] = switch_port4 pg2.out = switch_port2 switch_port2.out = branch2 branch2.outs[0] = switch_port3 branch2.outs[1] = switch_port4
0.5) #exploentioal arrival time sdist = functools.partial(random.expovariate, 0.01) #Mean size of packet 100 bytes #port_rate = float(functools.partial(random.expovariate,0.5)) # Servace Bit Rate port_rate = 1000.0 samp_dist1 = functools.partial(random.expovariate, 1.0) samp_dist2 = functools.partial(random.expovariate, 1.0) qlimit = 10000 #FIFO Queue Size env = simpy.Environment() pg = PacketGenerator(env, "Greg", adist, sdist) #Package Generator ps1 = PacketSink(env, debug=False, rec_arrivals=True) #Package Sink for packages ps2 = PacketSink(env, debug=False, rec_arrivals=True) switch_port1 = SwitchPort(env, port_rate, qlimit=10000) # define two queues switch_port2 = SwitchPort(env, port_rate, qlimit=10000) pm1 = PortMonitor(env, switch_port1, samp_dist1) #define port monitor pm2 = PortMonitor(env, switch_port2, samp_dist2) pg.out = switch_port1 '''switch_port1.out = ps1 ps1 = switch_port2 ''' switch_port1.out = switch_port2 switch_port2.out = ps2 env.run(until=2000) #print(ps2.waits[-10:])
env = simpy.Environment() # Create the packet generators and sink def selector(pkt): return pkt.src == "SJSU1" def selector2(pkt): return pkt.src == "SJSU2" ps1 = PacketSink(env, debug=False, rec_arrivals=True, selector=selector) ps2 = PacketSink(env, debug=False, rec_waits=True, selector=selector2) pg1 = PacketGenerator(env, "SJSU1", adist1, sdist) pg2 = PacketGenerator(env, "SJSU2", adist2, sdist) pg3 = PacketGenerator(env, "SJSU3", adist3, sdist) branch1 = RandomBrancher(env, [0.75, 0.25]) branch2 = RandomBrancher(env, [0.65, 0.35]) switch_port1 = SwitchPort(env, port_rate*2) switch_port2 = SwitchPort(env, port_rate*2) switch_port3 = SwitchPort(env, port_rate*2) switch_port4 = SwitchPort(env, port_rate*2) switch_port5 = SwitchPort(env, port_rate*7) # Wire packet generators, switch ports, and sinks together pg1.out = switch_port1 switch_port1.out = branch1 branch1.outs[0] = switch_port2 switch_port2.out = branch2 branch2.outs[0] = switch_port3 branch2.outs[1] = switch_port4 pg3.out = switch_port3 pg2.out = switch_port4 switch_port3.out = switch_port5
class Node(object): def __init__(self, id, env, gen): self.env = env self.id = id self.packet_generator = None self.gen = gen self.routes = {} self.routing_algorithm = None self.network = None self.env.process(self.run()) self.packet_sink = PacketSink(env=self.env, rec_arrivals=True) self.packets_to_send = simpy.Store(self.env, capacity=1) self.packets_sent = 0 self.switch_port = SwitchPort(env=env, rate=500, qlimit=64, limit_bytes=False, id=self.id) self.switch_port.out = self.packets_to_send #self.port_monitor = PortMonitor(env, self.switch_port, dist=1) def set_network(self, network): """ Set the network in which the node is placed in :param network: :return: """ self.network = network def set_routing_algo(self, controller): # put this router into the controller controller.setNode(self.id) if controller == "random": self.routing_algorithm = RandomRouting(gen=self.gen, node=self, graph=self.network) elif controller == "dijkstra": self.routing_algorithm = Dijkstra(graph=self.network, node=self) else: pass def route(self, packet): return self.routing_algorithm.route_packet(packet) def set_packet_generator(self, lbd, possible_destinations): def dst_dist(gen, destinations): if destinations is None: return None else: return gen.choice(destinations) def next_packet_time(gen, lbd_): return gen.exponential(lbd_) packet_dst = partial(dst_dist, self.gen, possible_destinations) next_pkt_time = partial(next_packet_time, self.gen, lbd) self.packet_generator = PacketGenerator(env=self.env, id="{}_pg".format(self.id), adist=next_pkt_time, sdist=100, dstdist=packet_dst) ## LOOK AT THIS AGAIN - might want to consider putting it into a switch port self.packet_generator.out = self.packets_to_send def get_port_id(self, dst_node_id): return "{}_{}".format(self.id, dst_node_id) def get_link_id(self, dst_node): return "{}_{}".format(self.id, dst_node.id) def add_connection(self, dst_node, rate, qlimit, monitor_rate, propagation_delay, bidirectional=True): """ Add a new connection to this node given the following set of parameters :param dst_node: :param rate: :param qlimit: :param monitor_rate: :param propagation_delay: :param bidirectional: :return: """ link_id = self.get_link_id(dst_node) new_link = Link(self.env, id=link_id, cost=propagation_delay, dst=dst_node, src=self.id) self.routes[link_id] = new_link if bidirectional: new_link_reverse = dst_node.add_connection(self, rate, qlimit, monitor_rate, propagation_delay, bidirectional=False) return [new_link, new_link_reverse[0]] return [new_link] def is_neighbour(self, node): """ Check if a certain node is a neighbour of this node :param node: Node name (str) to be searched for among the neighbours :return: Boolean indicating if the node is found """ if node == self: return False for link in self.routes.values(): if link.dst == node or link.src == node: return True return False def get_link_weight(self, node): pass def clear_packets(self): """ Clear all packets from the node's switch port :return: """ self.switch_port.clear_packets() def put(self, packet): if not isinstance(packet, Packet): return packet.set_current_node(self) if packet.dst == self.id: self.packet_sink.put(packet) else: self.switch_port.put(packet) print("Packet " + str(packet.id) + " put into node " + str(self.id)) def run(self): while True: packet = yield (self.packets_to_send.get()) outgoing_port = self.route(packet) if outgoing_port is not None and self.routes[ outgoing_port.id].state: # Increment counter in packet packet.increment_hops() packet.incrementRouteWeight(self.routes[outgoing_port.id].cost) packet.decrement_ttl() outgoing_port.put(packet) self.packets_sent += 1