/** Retira o próximo evento da fila de prioridades, e o trata. */ public void handleEvents() { // Não é esperado que esta lista esteja vazia... if (getEvents().isEmpty()) throw new RuntimeException(); // Evento é retornado e deletado da fila. Event event = getEvents().poll(); currentTime = event.getTime(); switch (event.getType()) { case CongestionPacketIntoRouter: handleCongestionPacketIntoRouterEvent(event); break; case TxPacketIntoRouter: handleTxPacketIntoRouter(event); break; case Timeout: handleTimeout(event); break; case RouterSuccessfullySentPacket: handleRouterSuccessfullySentPacket(event); break; case TxPacketHeadsToRouter: handleTxPacketHeadsToRouter(event); break; case SackArrives: handleSackArrives(event); break; default: throw new RuntimeException(); // Não deve existir outro evento... } }
private void handleTxPacketIntoRouter(Event event) { // Sempre que o roteador fica vazio, um novo envio é agendado. if (getSystem().getRouter().getBuffer().quantityOfRemainingPackets().intValue() == 0) { Event sendPack = new Event(EventType.RouterSuccessfullySentPacket); double packTransmission = packTransmission(SimulationProperties.getMSS()); sendPack.setTime(currentTime + packTransmission); getEvents().add(sendPack); } getSystem().getRouter().receivePacket(event.getPack(), currentTime); }
/** * Agenda eventos de envio e de chegada de pacote no roteador. * * @param tx Servidor de saída do pacote. */ private void newTxPacketHeadsToRouter(Tx tx) { Pack nextTcpPack = tx.sendPacket(currentTime); tx.setTransmiting(true); double propagation = setPropagationDelay(tx); Event endOfTransmition = new Event(EventType.TxPacketHeadsToRouter); endOfTransmition.setTime(currentTime + transmissionTimeMs); endOfTransmition.setTxIndex(tx.getIndex()); getEvents().add(endOfTransmition); Event routerReceivesTcp = new Event(EventType.TxPacketIntoRouter); routerReceivesTcp.setTime(currentTime + transmissionTimeMs + propagation); routerReceivesTcp.setPack(nextTcpPack); getEvents().add(routerReceivesTcp); Event timeout = new Event(EventType.Timeout); timeout.setTime(currentTime + tx.getRTO()); timeout.setTxIndex(tx.getIndex()); nextTcpPack.setTimeout(timeout); getEvents().add(timeout); if (tx.getNotDeliveredPacks().contains(nextTcpPack)) { int index = tx.getNotDeliveredPacks().indexOf(nextTcpPack); Pack p = tx.getNotDeliveredPacks().get(index); getEvents().remove(p.getTimeout()); tx.getNotDeliveredPacks().remove(index); } tx.getNotDeliveredPacks().add(nextTcpPack); }
private void handleTimeout(Event event) { Tx tx = getSystem().getTxs().get(event.getTxIndex()); if (!tx.isTransmiting()) { tx.handleTimeOutEvent(); newTxPacketHeadsToRouter(tx); } else tx.handleTimeOutEvent(); }
private void handleCongestionPacketIntoRouterEvent(Event event) { double scheduleTime = random.generateExponential(1.0 / congestionPacketFrequency); Event scheduleNextCongestionPack = new Event(EventType.CongestionPacketIntoRouter); scheduleNextCongestionPack.setTime(currentTime + scheduleTime); getEvents().add(scheduleNextCongestionPack); if (getSystem().getRouter().getBuffer().quantityOfRemainingPackets().equals(0)) { Event sendPack = new Event(EventType.RouterSuccessfullySentPacket); double packTransmission = packTransmission(SimulationProperties.getMSS()); sendPack.setTime(currentTime + packTransmission); getEvents().add(sendPack); } long numberOfCongestionPacks = Math.round(random.generateGeometric(1.0 / congestionPacketFrequency)); for (long i = 0; i < numberOfCongestionPacks; i++) getSystem().getRouter().receivePacket(new Pack(PackType.Congestion, 0), currentTime); }
private void handleRouterSuccessfullySentPacket(Event event) { SACK sack = getSystem().getRouter().sendPackToRx(currentTime); if (sack != null) { // Tráfego de fundo se perde int ackPropagation = getSystem().getTxs().get(sack.getDestination()).getGroup().equals(Group.Group1) ? SimulationProperties.getAckG1PropagationTime() : SimulationProperties.getAckG2PropagationTime(); Event sendSack = new Event(EventType.SackArrives); sendSack.setTime(currentTime + ackPropagation); sendSack.setSack(sack); getEvents().add(sendSack); } // Mais um pacote sai do roteador para um Rx. if (getSystem().getRouter().getBuffer().quantityOfRemainingPackets().intValue() >= 1) { Event sendPack = new Event(EventType.RouterSuccessfullySentPacket); double packTransmission = packTransmission(SimulationProperties.getMSS()); sendPack.setTime(currentTime + packTransmission); getEvents().add(sendPack); } }
private void handleSackArrives(Event event) { SACK sack = event.getSack(); Tx tx = getSystem().getTxs().get(sack.getDestination()); tx.receiveSack(sack, currentTime); if (!tx.isTransmiting()) if (tx.getNextPacketToSend() < tx.getOldestNotReceivedPacket() + tx.getCongestionWindow()) newTxPacketHeadsToRouter(tx); removeTimeouts(sack, tx); }
private void handleTxPacketHeadsToRouter(Event event) { Tx tx = getSystem().getTxs().get(event.getTxIndex()); if (tx.getNextPacketToSend() < tx.getOldestNotReceivedPacket() + tx.getCongestionWindow()) newTxPacketHeadsToRouter(tx); else tx.setTransmiting(false); }
/** * A fila de eventos precisa ser setada com eventos iniciais. Este método seta envios de pacotes * de congestionamento (tráfego de fundo) e também envios de pacotes vindo dos Txs. */ private void setFirstEvents() { resetSimulation(); // Prepara o tráfego de fundo. if (SimulationProperties.isWithCongestion()) { Event firstCongestionPack = new Event( EventType .CongestionPacketIntoRouter); // Evento "Pacote de Tráfego de Fundo chegar ao // roteador" firstCongestionPack.setTime(random.generateExponential(1.0 / congestionPacketFrequency)); getEvents().add(firstCongestionPack); } // Prepara os servidores para transmissão de Tx-Rx. for (Tx tx : getSystem().getTxs()) { double propagationDelay = setPropagationDelay(tx); // Fator aleatório além da propagação e da transmissão. // É zero por padrão, mas este intervalo muda nos cenários 2 e 3. double randTime = random.generateDouble() * SimulationProperties.getAssyncInterval(); Event packSent = new Event(EventType.TxPacketHeadsToRouter); // Evento "Pacote sair do Tx" packSent.setTime(randTime + transmissionTime); packSent.setTxIndex(tx.getIndex()); getEvents().add(packSent); Pack pack = tx.sendPacket(randTime); Event firstTcpPack = new Event(EventType.TxPacketIntoRouter); // Evento "Pacote TCP chegar ao roteador" firstTcpPack.setTime(randTime + transmissionTime + propagationDelay); firstTcpPack.setPack(pack); getEvents().add(firstTcpPack); Event possibleTimeout = new Event(EventType.Timeout); // Evento "Possível Timeout do pacote" possibleTimeout.setTime(randTime + tx.getRTO()); possibleTimeout.setTxIndex(tx.getIndex()); pack.setTimeout(possibleTimeout); getEvents().add(possibleTimeout); } }