# Simulation script for Nessi: CSMA protocols # # Copyright (c) 2003-2007 Juergen Ehrensberger # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """Laboratory TLI: CSMA This file configures a shared bus with multiple connected stations in order to evaluate the effect of the MAC protocol. The source application generates packets at a configurable rate. Collected statistics are: - "throughput": Line plot: Throughput in b/s - "waiting packets": Line plot: total number of waiting packets at nodes - "packet rate": Bar plot: Rate of transmitted packets per station - "retransmission rate": Bar plot: Rate of packet retransmissions per packet - "channel activities": Bar plot: Distribution of the number of simultaneous accesses to the channel, in time. """ from nessi.simulator import * from nessi.nodes import Host from nessi.media import IdealRadioChannel from nessi.devices import NIC from nessi.csma import IdealRadioPhy, AlohaDL, CSMADL, CSMA_CA_DL from nessi.trafficgen import PoissonSource, TrafficSink try: import psyco psyco.full() except ImportError: pass # --------------------------------------------------------------------------- # Create the network link = IdealRadioChannel() numHosts = 31 # CHANGE HERE FOR THE NUMBER OF NODES hosts=[] for i in range(numHosts): h = Host() h.hostname = "host"+str(i) niu = NIC() h.addDevice(niu,"eth0") niu.addProtocol(IdealRadioPhy(), "phy") niu.addProtocol(CSMA_CA_DL(), "dl") # CHANGE HERE FOR A DIFFERENT MAC h.eth0.attachToMedium(link, (i,i)) h.eth0.dl.setSrcAddress(i) hosts.append(h) # Attach a traffic sink to the first node server = hosts[0] sink = TrafficSink() server.addProtocol(sink, "app") server.eth0.dl.registerUpperLayer(sink) # Attach an traffic source with poisson traffic to all other nodes for h in hosts[1:]: source = PoissonSource() h.addProtocol(source, "app") source.registerLowerLayer(h.eth0.dl) h.eth0.dl.registerUpperLayer(source) h.eth0.dl.setDstAddress(0) # All notes transmit to the server. # --------------------------------------------------------------------------- # Define statistics to be traced class StatSampler: startTime = 0.0 channelOccupation = {} channelSamples = 0.0 def resetStats(self): self.startTime = TIME() self.channelOccupation = {} self.channelSamples = 0.0 for h in hosts: h.app.octetsReceived = 0 h.eth0.dl.packetsSent = 0 h.eth0.dl.packetRetransmissions = 0 def throughput(self): """Throughput as seen by the sink on the server.""" if TIME() > self.startTime: return server.app.octetsReceived*8 / (TIME()-self.startTime) else: return 0 def packetRate_perSrc(self): """Packet per second, for each source. Suitable for a bar plot.""" result = " " if TIME() > self.startTime: for i in range(numHosts): result += "%d,%f;"%(i,hosts[i].eth0.dl.packetsSent/ (TIME()-self.startTime)) return result[:-1] def retransmissionRate_perSrc(self): """Retransmissions per packet, for each source. For bar plots.""" result = " " for i in range(numHosts): sent = float(hosts[i].eth0.dl.packetsSent) if sent: result += "%d,%f;"%( i,hosts[i].eth0.dl.packetRetransmissions /sent) return result [:-1] def totalQueueLength(self): """Total packet number generated by the sources but not transmitted.""" queue = 0 for h in hosts: queue += len(h.eth0.dl._transmitQueue) return queue def channelActivities(self): """Frequency of different number of concurrent transmission on the channel. Suitable for bar plots.""" self.channelSamples += 1 numTr = server.eth0.phy._receiveActivities self.channelOccupation[numTr] = self.channelOccupation.get(numTr,0)+1 result = ';'.join(["%d,%f"%(x,y/self.channelSamples) for x,y in self.channelOccupation.items()]) return result stats = StatSampler() NEW_SAMPLER("throughput",stats.throughput,1.0, 'exponential') # Line plot NEW_SAMPLER("waiting packets",stats.totalQueueLength,1.0, 'exponential')#Line NEW_SAMPLER("packet rate",stats.packetRate_perSrc,1.0, 'exponential') #Bar plot NEW_SAMPLER("retransmission rate", stats.retransmissionRate_perSrc,1.0,'exponential') # Bar NEW_SAMPLER("channel activities", stats.channelActivities,1.0,'exponential') # Bar plot # =========================================================================== # MODIFY THE SIMULATION PARAMETERS HERE # SOURCE # ------ # Set the parameters of the source meanPDUSize = 100 # Mean packet size in bytes meanInterarrival = 1.0 # Mean time between sending packets for h in hosts[1:]: h.app.setPDUSize(meanPDUSize=100) # Exponentially distributed packet size h.app.setInterarrival(meanInterarrival) # Exponentially distributed # LINK # ---- dataRate = 1e6 # 1 Mb/s for h in hosts: h.eth0.phy.setDataRate(dataRate) # MAC protocol # ------------ # Set the backoff model backoffModel = 'exponential' slotTime = 0.001 # 1 ms maxSlots = 1023 for h in hosts: h.eth0.dl.setBackoffModel(backoffModel,slotTime,maxSlots) # Set the retransmission timeout timeout = 0.0105 for h in hosts: h.eth0.dl.retransmissionTimeout = timeout # =========================================================================== # Define functions that allow the user to interactively change the traffic # during the simulation def pdusize(pduSize): """Changes the mean pdu size of all sources.""" global meanPDUSize meanPDUSize = pduSize for h in hosts[1:]: h.app.setPDUSize(pduSize) stats.resetStats() rate = len(hosts[1:]) * meanPDUSize * 8 / meanInterarrival print "Total rate: ", rate, " bits/s" def interarr(interarrival): """Changes the mean pdu size of all sources.""" global meanInterarrival meanInterarrival = interarrival for h in hosts[1:]: h.app.setInterarrival(interarrival) stats.resetStats() rate = len(hosts[1:]) * meanPDUSize * 8 / meanInterarrival print "Total rate: ", rate, " bits/s" # =========================================================================== # Run the simulation for h in hosts[1:]: h.app.start() RUN(10000)