Exemplo n.º 1
0
 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         
Exemplo n.º 2
0
 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
Exemplo n.º 3
0
    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
Exemplo n.º 4
0
    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)
Exemplo n.º 5
0
    # 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
Exemplo n.º 6
0
    # 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
Exemplo n.º 7
0
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,
Exemplo n.º 8
0
 def _create_switchport(self, rate, qlimit, outgoing_port_id):
     return SwitchPort(self.env,
                       rate=rate,
                       qlimit=qlimit,
                       limit_bytes=False,
                       id=outgoing_port_id)
Exemplo n.º 9
0
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))
Exemplo n.º 10
0
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
Exemplo n.º 11
0
    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
Exemplo n.º 12
0
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)
Exemplo n.º 13
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:])
Exemplo n.º 15
0
    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
Exemplo n.º 16
0
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