📄 riprouter.java
字号:
// log / record .... if (super.reportWriter_ != null) { super.write(""); super.write("receive incoming, " + pkt + ", delay, " + nextTime); super.write("break this packet into, " + numPackets); } // break a large packet into smaller ones that fit into MTU // by making null or empty packets except for the last one for (int i = 0; i < numPackets - 1; i++) { NetPacket np = new NetPacket(null, pkt.getID(), MTU, tag, pkt.getSrcID(), pkt.getDestID(), pkt.getNetServiceType(),i+1,numPackets); np.setLast(id); super.write("enqueing, " + np); sched.enque(np); // put the packet into the scheduler } // put the actual packet into the last one and resize it accordingly pkt.setLast(id); pkt.setSize(pkt.getSize() - MTU * (numPackets - 1)); super.write("enqueing, " + pkt); sched.enque(pkt); // put the packet into the scheduler } /** * Gets the link's name for a given id * @param destID a destination id * @return the link's man * @pre destID > 0 * @post $none */ private synchronized String getLinkName(int destID) { String destName = GridSim.getEntityName(destID); String linkName = null; //directly connected if (hostTable.containsValue(destName)) { linkName = (String)linkTable.get(destName); } else { // need to forward to another router Object[] data = (Object[]) forwardTable.get(destName); String router = (String) data[0]; linkName = (String) linkTable.get(router); } return linkName; } /** * Returns the Scheduler associated with a packet. * * @param np NetPacket for which the associated scheduler is to be returned * @return the packet's scheduler or <tt>null</tt> if the packet is empty * @pre np != null * @post $none */ public PacketScheduler getScheduler(Packet np) { if (np == null) { return null; } String destName = GridSim.getEntityName( np.getDestID() ); return getScheduler(destName); } /** * Returns the Scheduler that the router would use to reach a particular * destination. This can be used to set weigths, priorities etc. as the * case may be on the Scheduler * * @param dest id of the destination for which the Scheduler is required. * @return the destination's packet scheduler * @pre dest > 0 * @post $none */ public PacketScheduler getScheduler(int dest) { if (dest < 0) { return null; } String destName = GridSim.getEntityName(dest); return getScheduler(destName); } /** * Returns the Scheduler that the router would use to reach a particular * destination. This can be used to set weigths, priorities etc. as the * case may be on the Scheduler * * @param dest Name of the destination for which the Scheduler is required. * @return destination's packet scheduler or <tt>null</tt> if destination * name is invalid. * @pre dest != null * @post $none */ public PacketScheduler getScheduler(String dest) { if (dest == null || dest.length() == 0) { return null; } PacketScheduler sched = null; try { if ( hostTable.containsValue(dest) ) { String linkName = (String) linkTable.get(dest); sched = (PacketScheduler) schedTable.get(linkName); } else { // need to forward to another router Object[] data = (Object[]) forwardTable.get(dest); // in case the forwarding table is incomplete if (data == null) { return null; } String router = (String) data[0]; String linkName = (String) linkTable.get(router); sched = (PacketScheduler) schedTable.get(linkName); } } catch (Exception e) { sched = null; } return sched; } /** * Processes internal event * @param ev a Sim_event object * @pre ev != null * @post $none */ private synchronized void processInternalEvent(Sim_event ev) { PacketScheduler sched = (PacketScheduler) ev.get_data(); dequeue(sched); } /** * Dequeue a packet from the scheduler and sends it to the next * destination via a link. * @param sched the packet scheduler * @pre sched != null * @post $none */ private synchronized void dequeue(PacketScheduler sched) { Packet np = sched.deque(); // process ping() packet if (np instanceof InfoPacket) { ((InfoPacket) np).addExitTime( GridSim.clock() ); } super.write("dequeuing, " + np); // must distinguish between normal and junk packet int tag = GridSimTags.PKT_FORWARD; if (np.getTag() == GridSimTags.JUNK_PKT) { tag = GridSimTags.JUNK_PKT; } // sends the packet via the link String linkName = getLinkName( np.getDestID() ); super.sim_schedule(GridSim.getEntityId(linkName), GridSimTags.SCHEDULE_NOW, tag, np); // process the next packet in the scheduler if ( !sched.isEmpty() ) { double nextTime = (np.getSize() * BITS) / sched.getBaudRate(); sendInternalEvent(nextTime, sched); } } /** * Sends an internal event to itself * @param time the delay time period * @param data the data to be sent * @return <tt>true</tt> if it is successful, <tt>false</tt> otherwise * @pre time >= 0 * @post $none */ private synchronized boolean sendInternalEvent(double time, Object data) { if (time < 0.0) { return false; } super.sim_schedule(id, time, GridSimTags.INSIGNIFICANT, data); return true; } /** * Prints this router's routing table in a nice-formatted layout * @pre $none * @post $none */ public synchronized void printRoutingTable() { synchronized (System.out) { System.out.println(); System.out.println("--- Routing Table for " + super.get_name() + " ---"); for (Enumeration e = hostTable.keys(); e.hasMoreElements(); ) { String link = (String) e.nextElement(); System.out.println(hostTable.get(link) + "\t\t" + link); } for (Enumeration e = forwardTable.keys(); e.hasMoreElements(); ) { String host = (String)e.nextElement(); Object[] data = (Object[])forwardTable.get(host); String nextHop = (String)data[0]; System.out.println(host + "\t\t" + nextHop); } System.out.println("-------------------------------------"); System.out.println(); } } //----------- ADVERTISING FUNCTIONS --------------// /** * All hosts connected to this router are advertised to adjacent routers * @pre $none * @post $none */ protected synchronized void advertiseHosts() { Collection hosts = hostTable.values(); // who to advertise Enumeration routers = routerTable.elements(); while ( routers.hasMoreElements() ) { RIPAdPack ad = new RIPAdPack(super.get_name(), hosts); String router = (String) routers.nextElement(); super.write("advertise to router, " + router); sim_schedule(Sim_system.get_entity_id(router), GridSimTags.SCHEDULE_NOW, GridSimTags.ROUTER_AD, ad); } super.sim_pause(5); // wait for 5 secs to gather the results } /** * When an ad is recieved, the forwarding table is updated. After that we * need to propogate this ad along all links except the incoming one. * {@link #forwardAd(RIPAdPack)} is used for that * @param ev a Sim_event object * @pre ev != null * @post $none */ private synchronized void receiveAd(Sim_event ev) { super.write("receive router ad from, "+GridSim.getEntityName(ev.get_src())); // what to do when an ad is received RIPAdPack ad = (RIPAdPack)ev.get_data(); // prevent count-to-infinity if (ad.getHopCount() > 15) { return; } String sender = ad.getSender(); Iterator it = ad.getHosts().iterator(); while ( it.hasNext() ) { String host = (String) it.next(); if ( host.equals(super.get_name()) ) { continue; } if (hostTable.containsValue(host)) { // direct connection continue; } if (forwardTable.containsKey(host)) { Object[] data = (Object[])forwardTable.get(host); int hop = ((Integer)data[1]).intValue(); if ((hop) > ad.getHopCount()) { Object[] toPut = { sender, new Integer(ad.getHopCount()) }; forwardTable.put(host, toPut); } } else { Object[] toPut = { sender, new Integer(ad.getHopCount()) }; forwardTable.put(host, toPut); } } forwardAd(ad); } /** * Received ads should be forwarded along all links except the incoming * one. Also need to change id to onself * * @param ad a RIPAdPack object * @pre ad != null * @post $none */ private synchronized void forwardAd(RIPAdPack ad) { String sender = ad.getSender(); ad.incrementHopCount(); RIPAdPack newad = new RIPAdPack(super.get_name(),ad.getHosts()); newad.setHopCount(ad.getHopCount()); Enumeration routers = routerTable.elements(); while ( routers.hasMoreElements() ) { String router = (String)routers.nextElement(); if (!router.equals(sender)) { sim_schedule(Sim_system.get_entity_id(router), GridSimTags.SCHEDULE_NOW, GridSimTags.ROUTER_AD, newad); } } }} // end class
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -