显示标签为“ns2”的博文。显示所有博文
显示标签为“ns2”的博文。显示所有博文

2008年7月7日星期一

802.11 MAC code in NS-2 (version 2.28 )

非常详细介绍ns2里的802.11MAC代码的一篇文章.非常有用噢~~~

802.11 MAC code in NS-2 (version 2.28 )

by Joshua Robinson (jpr at rice.edu)
Last update: 4-29-05

Please send me any comments, questions, suggestions, or corrections

Transmitting a packet

Roughly takes the following path (when no errors or congestion):

recv() -> send() -> sendDATA() and sendRTS() -> start defer timer

-> deferHandler() -> check_pktRTS() -> transmit()

-> recv() -> receive timer started

-> recv_timer() -> recvCTS() -> tx_resume() -> start defer timer -> rx_resume()

-> deferHandler() -> check_pktTx() -> transmit()

-> recv() -> receive timer started

-> recv_timer() -> recvACK() -> tx_resume() -> callback_ -> rx_resume() -> done!

When the first RTS fails:

recv() -> send() -> sendDATA() and sendRTS() -> start defer timer

-> deferHandler() -> check_pktRTS() -> transmit -> start send timer

-> send_timer() -> RetransmitRTS() -> tx_resume() -> backoff timer started

backoffHandler() -> check_pktRTS() -> transmit

the rest is the same as above

Receiving a packet

Roughly takes the following path (when no errors or congestion):

recv() -> receive timer started

-> recv_timer() -> recvRTS() -> sendCTS() -> tx_resume() -> start defer timer -> rx_resume()

-> deferHandler() -> check_pktCTRL() -> transmit()

-> recv() -> receive timer started

-> recv_timer() -> recvDATA() -> sendACK() -> tx_resume() -> start defer timer -> uptarget_->recv()

-> deferHandler() -> check_pktCTRL() -> transmit() -> start send timer

-> send_timer() -> tx_resume() <- nothing happens, we’re done!

Functions

recv() (DOWN) - Like all connectors, which Mac inherits from, the packet to be sent is received by the recv() function. Because the recv() function is also called when a packet comes from the channel, recv() checks the direction field in the packet header. If the direction is DOWN, meaning the packet came from an upper layer, the packet is then passed on to the send() function.

recv() (UP) – The recv() function is called whenever a packet is received from either an upper or lower layer. If the packet is received from a lower layer – the network interface here, then the first check will be skipped. At this point the phy has just received the first bit of the incoming packet, but the MAC can’t do anything with the packet until the whole packet is received. If the packet is received while the MAC is currently transmitting another packet, then the received packet would be ignored – meaning the error flag in the packet’s header is set. If the MAC is not currently receiving any packets, then the rx_state_ is changed to RECV and checkBackoffTimer is called. Afterwards, the incoming packet is assigned to pktRx_ and the receive timer is started for the txtime() of the packet. If the MAC was already receiving a packet when this packet arrived, it will compare the received power of the new packet with the old packet. If the power of the new packet is smaller than the old packet by at least the capture threshold, the new packet will be ignored (captured) and the capture() function is called. If the power levels of the two packets are too close though, there will be a collision and control will transfer to collision(), which will drop the arriving packet. The original packet won’t be dropped until it’s reception is complete. Control will return to the MAC whenever the receive timer expires, calling recvHandler(), which in turns goes right to recv_timer().

send() - The send() function first checks the energy model, dropping the packet if the node is currently in sleep mode. It then sets callback_ to the handler passed along with the packet. This is so the handler can be called when the packet’s transmission is complete. Next, send() calls sendDATA() and sendRTS which build the MAC header for the data packet and the RTS packet to go along with the data packet – which are stored in pktTx_ and pktRTS_ respectively. The MAC header for the data packet is then assigned a unique sequence number (with respect to the node).
Next, the MAC checks it’s backoff timer. If the backoff timer is not currently counting down, then the node checks if the channel (medium) is idle, and if so the node will begin to defer. The node checks this using the function is_idle(). As per the 802.11 specs, the node will defer a difs time plus a randomly chosen amount of time in the interval [0, cw_), where cw_ is the current contention window. If the node is already waiting on it's defer timer, it will just continue waiting (not resetting the timer). If the medium is detected to be busy, then the node starts it's backoff timer. As of this point, the send() function has finished and control will resume when one of the timers expires, calling either deferHandler() or backoffHandler().

sendDATA() - This function builds the MAC header for the data packet. This involves increasing the size of the packet, setting the type as data, and subtype as data. The packet should now have a complete MAC header attached to it. The function then stores the txtime of the packet, which is computed by the txtime() function. By txtime, we basically mean the size of the packet multiplied by the Data rate. You'll notice (in 2.28 at least), that this calculation is done twice – this first time is just a waste. It's calculated again because a different value for the data rate is used if the packet happens to be a broadcast packet. Also, if the packet is not a broadcast packet, the duration field in the MAC header is computed. By duration, we mean the amount of time this communication still needs the channel after the data packet has been transmitted. For the case of a data packet, this corresponds to the amount of time to transmit an ACK plus a short inter-frame spacing. If the packet happens to be broadcast, this field is set to zero (no ACKs for broadcast packets). Now, the MAC has finished building the MAC header for the packet and finally assigns the internal variable pktTx_ to point to the packet we've been working on. This is essentially a way of storing the packet to be transmitted in a local buffer in the MAC. Now, the code returns to the send() function.

sendRTS() – This function is in charge of creating an RTS packet with the specified destination in conjunction with the data packet the MAC is trying to send. The first thing it does is check the size of the packet against the RTSThreshold. If the packet is smaller (or is broadcast) then no RTS is sent before the data is transmitted (the RTS/CTS mechanism is not used). In this case, the function simply returns control back to the send() function. Otherwise, a brand new packet is created (actually done in the first line of the function) and it's fields are set appropriately, i.e. the type is set as a MAC packet. A rts_frame structure is used to fill in the rest of the packet header and the appropriate values are put in the rts fields. The destination field is filled in with the parameter passed to the function and the rf_ta (source?) is filled in with the MAC's address. The duration field is also calculated as the time to transmit a CTS, the data packet (pktTx_) and an ACK (plus 3 sifs). After the RTS has been constructed, the internal state variable pktRTS_ is assigned a pointer to the new RTS. After this, control is returned to the send() function.

sendCTS() - This function is in charge of creating a CTS packet and pointing pktCTRL_ to it. Everything proceeds straightforwardly, with fields being given obvious values. The duration field is set to be the same as was in the RTS, except minus the txtime of a CTS and a sifs_ time, since that amount of time would have already elapsed once another station decoded the packet. After the creation of the CTS packet is done, pktCTRL_ is pointed to the new packet and control returns to recvRTS().

sendACK() - This function is responsible for creating an ACK packet to be sent in response to a data packet. The packet is created and all the fields are filled in with the obvious values. The duration field is set to zero indicating to other nodes that once this ACK has completed, they don't need to defer to another communication. Once the packet has been successfully built, pktCTRL_ is pointed to the new ACK and control returns to recvDATA().

deferHandler() - This function is called when the defer timer has expired. When this happens, this means the node has waited enough time before transmission to lessen the chance of collision and will now attempt to transmit a packet. Accordingly, the first thing the function does is assert that there is either a control, RTS, or data packet waiting to be transmitted. The function then calls check_pktCTRL(), and then makes sure the backoff timer is not currently running. Afterwards, it calls check_pktRTS() and check_pktTx(). If any of these check_ functions returns a value of zero, the defer handler stops, as this indicates that the check_ function has succeeded in transmitting that particular kind of packet. Therefore, the actual packet transmission is handled by one of these check_ functions. At this point, transmission has most likely begun on some kind of packet and control will resume at the expiration of the interface timer, txHandler(), which simply clears the flag tx_active_ to indicate that the phy is not currently transmitting something. Control will resume if another packet is received via recv(): a CTS if an RTS was just sent, a data packet if a CTS was just sent, or an ACK if a data packet was just sent. But control may also resume at the expiration of the send timer, sendHandler(), which immediately calls send_timer().

check_pktCTRL() - This function is responsible for transmitting CTS and ACK packets, which would be pointed to by pktCTRL_ . So the first thing the function does is check to see if this variable points to anything. If not, the function returns -1, indicating nothing was transmitted. The function will also return if the transmission state (tx_state_) indicates the MAC is currently transmitting either a CTS or ACK packet, although I don't know why this would occur. The function then performs a switch based on what kind of control packet is ready to be sent, CTS or ACK.
If it's a CTS, the MAC will check the status of the medium using is_idle(). If the channel is busy, the CTS will simply be dropped and pktCTRL_ set to zero. If the channel is idle, the function will, using macros, set the value of the tx_state_ to indicate the MAC is currently transmitting a CTS and then call the function checkBackoffTimer(). After this, the function calculates the timeout value – which is how long the MAC should wait before it decides the packet it sent wasn't received successfully. In the case that the control packet is an ACK, the MAC proceeds in the same way, except that it doesn't check the medium. Finally, the function transmit() is called with arguments pktCTRL_ and the previously calculated timeout value. At this point, the phy has just begun transmission of the control packet.

check_pktRTS() - This function, like the other two check_ functions, is responsible for transmitting a packet – in this case, an RTS packet. If there is no RTS packet ready to send, i.e. pktRTS_ is null, then the function simply returns with a value of -1, indicating that it did not send a packet. There is an oddly placed switch statement here presumably in order to detect an improperly built RTS packet. Before the RTS is sent, the channel is checked. If it is sensed to be busy, the contention window (cw_) is doubled using the inline function inc_cw() and the backoff timer is started again. The function therefore returns without transmitting a packet if the channel is busy. If the channel is idle, the tx_state_ of the MAC is set to RTS and the function checkBackoffTimer() is invoked. Next, the timeout value is calculated so that the MAC will know how long to wait for a CTS to be returned. Finally the function transmit() is called with arguments of the RTS packet and timeout value. At this point, the phy has begun transmission of the RTS packet.

check_pktTx() - This function, like the other two check_ functions, is responsible for transmitting a packet – in this case, the actual data packet. If there is no data packet waiting to be sent (pktTx_ is null), then the function returns with a value of -1, indicating that nothing was transmitted. Again, an oddly chosen switch statement is used to catch an improperly built data packet. If the channel is sensed to be busy, sendRTS is called. This means that despite the RTS/CTS exchange, another node is using the channel (possibly due to mobility), or RTS is not being used – in which case the sendRTS function will do nothing. Additionally, the contention window (cw_) is doubled using the inline function inc_cw() and then the backoff timer is started so that the MAC will remain idle until the other node has completed transmission. If the channel is idle, the tx_state_ is set to MAC_SEND and the checkBackoffTimer function is invoked. The timeout value is calculated in two ways, depending on whether or not the data packet is broadcast. If not, the timeout is how long the MAC should wait before it decides an ACK wasn't received. If the packet is broadcast, the timeout is simply the transmission time of the packet because no ACKs will be sent in conjunction with a broadcast packet. Finally, the function transmit() is invoked with arguments of the data packet and the calculated timeout value. At this point, the data packet has begun transmission.

checkBackoffTimer() - This inline function performs two checks. First, if the medium is idle and the backoff timer is currently paused, it will resume the timer.
The second check is if the medium is not idle and the backoff timer is currently running (busy and not paused), then it will pause the timer. This corresponds to the fact that the MAC only counts down it's backoff timer while the channel is idle. As per the specs, the timer should not be running while the channel is being used by another node.

transmit() – This function takes two arguments, a packet and a timeout value. It sets a flag variable, tx_active_, to one to indicate that the MAC is currently transmitting a packet. The function then performs a check because if it is an ACK being transmitted then it is possible that the node could be receiving a packet, in which case that packet would be missed. This next block checks if the MAC is currently receiving a packet and that it is an ACK being transmitted, and if so, marks the packet being received as having errors. Next, the packet is actually passed down to the network interface (WirelessPhy class) which is pointed to by downtarget_. Actually, only a copy of the packet is sent down in case there needs to be a retransmission. Finally, two timers are started – the send timer is started with the timeout value, which will alert the MAC that the transmission probably failed. Also, the interface timer(mhIF_) is started with the txtime() of the packet – when this timer expires, the MAC will know that the phy has completed the transmission of the packet.

send_timer() - This function is called at the expiration of the TxTimer, mhSend_. This timer expires after amount of time calculated as timeout in the corresponding check_ function – the expiration of this timer means slightly different things depending on which kind of packet was sent. In a switch statement, the MAC checks the value of tx_state_ to find out the kind of packet that was most recently sent and then handles each packet differently. If the last packet sent was an RTS, the expiration of the timer means a CTS wasn't received, presumably because the RTS collided or the receiving node is deferring. The MAC responds by attempting to retransmit the RTS in the function RetransmitRTS().
If the last packet sent was a CTS packet, the expiration of the timer means that no data packet was received. This is an infrequent event occurring if the CTS packet collided or if the data packet was in error. The MAC handles this by simply resetting itself to an idle state. This involves freeing the CTS packet stored in pktCTRL_.
If the last packet sent was a data packet, the expiration of the timer means that an ACK was not received. The MAC handles this situation by calling RetransmitDATA().
Finally, if the last packet sent was an ACK, the expiration of the timer simply means that the ACK has been transmitted, as no response is expected from an ACK. The MAC frees the ACK packet pointed to by pktCTRL_ .
After each case has been handled and a packet has possibly been prepared for retransmission, the function tx_resume() is given control. If a packet is going to be retransmitted, the backoff timer has already been started with an increased contention window.

RetransmitRTS() - This function is called in response to a CTS not being received after an RTS was sent. First, the function does some stat collecting, recording this as a failed RTS, and the short retry count (ssrc_) is incremented. The short retry count is maintained so the MAC knows when to give up on this packet and drop it, which happens when ssrc_ reaches the value of ShortRetryLimit in the MAC MIB. The drop is handled by called the discard() function on the RTS packet and resetting the pktRTS_ pointer to zero. Then the data packet is also dropped by calling the same discard() function. The ssrc_ is reset to zero and the contention window is reset to it's initial value. Otherwise, the same RTS pointed to by pktRTS_ is kept, but a retry field in the RTS is incremented. Because of the contention avoidance mechanism, the contention window is doubled and then the backoff timer is started using this new contention window. This means control will eventually return to backoffHandler().

RetransmitDATA() - This function is called when an ACK is not received in response to a data packet being sent. If the data packet was a broadcast packet, an ACK shouldn't be expected and so the data packet is treated as being successfully transmitted and so is freed and the congestion window reset. The backoff counter is started though, I'm not really sure why. Two separate retry counts are maintained depending on whether or not an RTS is being used for this data packet. If an RTS is not being used, the short retry limit is used, otherwise the long retry limit is used as a threshold. If the retry count has exceeded the threshold, then the data packet is discarded using the discard() function and the retry count and congestion window are reset. If the retry count has not been exceeded, the data packet is prepared for retransmission by incrementing a retry field in the mac header, doubling the congestion window, and then starting the backoff timer. This means control will eventually return to backoffHandler().

tx_resume() - This function is called when the MAC is getting ready to send a packet but needs to set some timers. If a control packet (CTS or ACK) is waiting to be sent, this function simply starts the defer time for a sifs_ amount of time. This is because a node is supposed to wait a brief period of time before transmitting. If an RTS packet is waiting to be sent, then the MAC makes sure the backoff timer isn't currently busy – if it is, then the MAC will wait to start the defer timer. If the backoff timer isn't busy the defer timer is started for a random time in the interval [0,cw_) plus a difs_ time. If a data packet is next to be sent, and MAC isn't currently backing off, then the defer timer is started for the data packet. If an RTS wasn't used for this packet, then the defer timer is set for a random value in the interval [0,cw_] plus a difs_ time, but if an RTS was used, the MAC will only defer for a sifs_ time. This is because if an RTS was used, then the channel has already been reserved for this MAC and it shouldn’t need to worry about collisions.
If there are no packets waiting to be sent, but the callback_ is defined, then it is handled, corresponding to a successfully completed packet transmission. Finally, the tx_state_ is set to idle. Control will return back to the MAC when the defer timer has expired, deferHandler() - or back to the function that called it, like one of the recvP functions.

capture() - This function is called when a second packet is received while the MAC is currently receiving another packet, but the second packet is weak enough so that the phy can ignore it. The important thing this function does is update the NAV so that carrier sense will know that the channel is still busy after it has finished receiving it’s packet. Capture also discards the captured packet.

collision() - The collision handler first checks the rx_state_ variable and sets it to MAC_COLL in case this is the first collision during the current packet. If a third packet collides, rx_state_ will already be MAC_COLL. Then, the MAC calculates how much longer the new packet will last and how much longer the old packet will last. If the new packet will last longer, then the MAC makes the new packet pktRx_ and resets the receive timer, mhRecv_. In this case the old packet is discarded here, but if the old packet will last longer then the new packet is simply discarded and pktTx_ doesn’t change. So at the end of this function, the colliding packet that would have completed first has been discarded and rx_state_ is set to MAC_COLL.

recv_timer() - This is the receive timer handler, called when mhRecv_ expires (though indirectly though RecvHandler). The expiration of the receive timer means that a packet has been fully received and can now be acted upon. First, the MAC checks to see if it’s currently transmitting a packet by checking the flag, tx_active_. If so, the MAC wouldn’t not have even heard the packet so it is just discarded (without updating NAV). Next, the rx_state_ is checked to see if there was a collision during this packet, i.e. rx_state_ equals MAC_COLL. If so, then pktRx_ is the colliding packet that lasted longest and now needs to be discarded. The NAV is also set for an eifs_ time, which is the amount of time the MAC must wait after a collision. The MAC then checks the packet for errors, and discards the packet if any were detected. Again, the NAV is set for eifs_ time after the error packet is finished being received. The next check the MAC performs is if the packet is actually destined for itself – if not, the MAC updates the NAV for the value in the duration field in the MAC header (not necessary just the txtime of the packet). This is of course so that the MAC doesn’t attempt to transmit while other nodes are using the channel. The next check consists of sending the packet to any taps if it is a data packet – essentially sending the packet to anybody wanting to listen in promiscuous mode. The next check involves the adaptive fidelity algorithm and basically keeping track of the nodes within radio range of the node. And finally, the last check performed is address filtering, where all packets that are not destined for the current node are discarded. The NAV would have already been updated so there’s no need to do anything else with the packet.
Now the MAC decides what to do based on what kind of packet it just received. If the packet is of MAC_Type_Management, it’s simply dropped. If it’s an RTS packet, recvRTS() is called, if CTS or ACK, then recvCTS() or recvACK() is called. And not surprisingly, if it’s a data packet, then recvDATA() is called. After this, pktRx_ is set to zero and control to given to rx_resume().

recvRTS() - This function is called by recv_timer after a full RTS packet has been received. If the tx_state_ is not idle, then the packet wouldn’t have been heard, so it’s simply discarded. Also, if the MAC is currently responding to another node (pktCTRL_ is nonzero) then the RTS will be ignored. This happens for example, if the node already heard an RTS from another node is waiting to send a CTS back. Otherwise, the MAC is in a state such that it can receive a packet, so it prepares to send a CTS by calling sendCTS(). Next, the MAC stops the defer time and calls tx_resume() - which will restart the defer timer for the appropriate amount of time. Control then returns to recv_timer().

recvCTS() - This function is called by the recv_timer after a full CTS packet has been received, meaning the MAC can now send it’s data. Since the MAC has no use for the RTS packet it just transmitted, it’s freed and pktRTS_ is set to zero. The send timer is stopped, although I’m not exactly sure why it would be running. Control then goes straight to tx_resume(), which sets the defer timer, and then control finally returns back to recv_timer().

recvACK() - This function is called by the recv_timer after a full ACK packet has been received, indicating a successful data transmission. First, the MAC checks that it really did just sent a data packet (tx_state == MAC_SEND) and discards the ACK if it didn’t. The MAC now knows that it just succesfully transmitted it’s data packet, so it frees pktTx_ and sets it to zero. The send timer is also stopped, but again, I don’t know why. The MAC then resets the appropriate retry count, short if an RTS wasn’t used, long if it was. Also, the congestion window is reset and the MAC starts its backoff timer so it won’t just immediately send again. Control then goes to tx_resume() and then back to recv_timer(). In tx_resume(), since there are no packets ready to send, the callback will be invoked, effectively telling the interface queue to send down another packet for transmission.

recvDATA() - This function is called by the recv_timer after a full data packet has been received, indicating that this node just successfully received a data packet. First, the MAC strips the MAC header from the packet, getting it ready to be sent to the upper layers. If the data packet wasn’t broadcast, RTS packets are being used, and tx_state_ indicates that the last packet the MAC sent was a CTS, then that CTS (pktCTRL_) is cleaned up (freed and pktCTRL_ set to zero). And again, the send timer is stopped. If the MAC didn’t just send a CTS when it should have, the data packet is dropped because events didn’t happen in the right order and the function returns. Otherwise, the data packet was received correctly and the MAC prepares to send an ACK by calling sendACK() and then tx_resume() to start the defer timer appropriately. If a CTS was not sent (because there was no corresponding RTS), then the MAC checks pktCTRL_. If there is a control packet there, the MAC will drop the data packet because there is no room to buffer an ACK packet (the ACK would go in pktCTRL_). Otherwise, sendACK() is called to create an ACK packet to send. In this case, if the send timer isn’t currently counting down, tx_resume() is called to start the defer timer.
Next, the MAC updates it’s sequence number cache – if the packet is unicast only. The packet is checked to make sure the source node will fit in the cache – it is possible for the cache to have been configured with an incorrect size, i.e. less than the total number of nodes in the system. Then the sequence number of the packet just received is compared with the most recently received sequence number and if they match, the data packet is discarded as it is a duplicate (same packet received twice). If the source node is not in the cache (cache is too small), some warnings are printed out.
The data packet is then passed to the uptarget_ - the layer above the MAC (usually link-layer). This means the data packet has been fully received by the node and it’s on it’s way up the protocol stack.

rx_resume() - This simple function is called after recv_timer has completed. All it does is set the rx_state_ to idle and then invoke checkBackoffTimer().

backoffHandler() - This function is called whenever the backoff timer expires. This function first checks to see whether there is a control packet (CTS or ACK) waiting to be sent. If so, it makes sure that the MAC is either sending the packet or deferring before sending the packet. If there was no control packet, check_pktRTS() is called. If there was no RTS packet, then check_pktTx() is called. This means, that at the expiration of the backoff timer, an RTS or a data packet will be transmitted if either is waiting. I think this should only happen on RTS or data retransmissions.

txHandler() - Handler for IFTimer that simply clears a flag in the MAC to indicate that the radio is no longer active.

command() - The command() function is a TCL hook for all the classes in ns-2 which allows C++ functions to be called from a TCL script. The arguments for command() are effectively the same as for the main function is basic C programs, with argc and argv containing the command given to the object. In the 802.11 MAC, this function is not often used, at least in my experience. If none of the commands match those specific to the 802.11 MAC, then the command() function of the parent class is called.

Timers
The timers are defined in the files mac/mac-timers.h/cc while the handlers (functions called when the timer expires) are in mac-802_11.cc.

IFTimer – The interface timer keeps tracks of how long the interface will be in transmit mode. This is only the time when the interface is actively transmitting bits into the air. The handler for this timer is txHandler(). Probably the simplest timer used by the MAC layer.

NavTimer – Started at the reception of a packet for the length of time indicated in the duration field of the MAC header. Calls navHandler() on expiration.

RxTimer – Started when the first bit of a packet is received and set for the length of time the packet will require to be completely received. This timer is needed because in simulation the entire packet is available as soon as the first bit arrives, but the MAC should not access the packet until it would have been completely received in reality. In the case of a packet collision, the receive timer is reset to expire at the end of the last colliding packet. The timer indirectly calls recv_timer() on expiration by calling recvHandler() first.

TxTimer – Indicates the time by which an ACK/CTS should have been received. The TxTimer (mhSend_) is started when a packet is transmitted by the transmit() function. Each type of packet has an expected response, for example, an RTS packet expects a CTS packet to follow. The timer is therefore stopped when a CTS, data, or ACK packet is received. The timer is not started on transmission of an ACK packet as there is no response expected. On expiration, send_timer() is called indirectly by first calling the (ahem, worthless) function sendHandler().

DeferTimer

BackoffTimer

BeaconTimer – Not used.

转自:

http://www.ece.rice.edu/~jpr/ns/docs/802_11.html



......

[Read More...]

2008年7月6日星期日

比较多信道多接口ns2扩展: “Aguero.C.R” VS “MW-Node”

I try in this post to sum up and explicit the main differences between
the approach proposed by R.Aguero et al. in their how-to and ours with
the MW-Node. I hope it helps you choosing what better fits your needs.

1) R.Aguero et al., "Adding Multiple Interface Support in NS-2"
(document, http://personales.unican.es/aguerocr)

This document describes changes to enable support of multiple
interfaces. By to support multiple interfaces they mean to allow to have
more than one wireless stack below a single routing agent on a
MobileNode. All the wireless stacks are identical (same Mac/Phy). The
routing agent code has to be modified to handle more than one wireless
stack. This applies only to AODV-like routing agents, that is routing
agents using the standard MobileNode, not the SRNode (DSR) or the
AODVUUNode (AODV-UU) for example.

This functionality is basically what is provided by Hyacinth
(http://www.ecsl.cs.sunysb.edu/multichannel/), some flexibility added.
To this respect their contribution is to me very similar to the
resources available at http://www.cse.msu.edu/~wangbo1/ns2/nshowto8.html

2) Module-based Wireless Node (MW-Node patch + documentation,
http://www.q2s.ntnu.no/~paquerea/ns.html)

In the following, I focus on the main features of the MW-Node. For
implementation details and design choices please refer to the documentation.

A MW-Node is a standard Node (not a MobileNode) with capabilities -
wireless, mobility, (energy support, not functional yet) - added by
means of modules.

The purpose of this new design of wireless and mobile networking support
in ns2 is twofold:
- to support new features such as multiple channels/multiple interfaces, and
- to provide a common basis for implementation of any wireless routing
protocol instead of having each routing protocol as a particular case
(not to say a particular node object) as it is with the MobileNode.

We distinguish between:
- multiple channels: one single routing object handling several wireless
interfaces possibly on different channels, and
- multiple interfaces: several interfaces, possibly of different types
(e.g different Mac/Phy), with one routing object handling one interface.

Following these definitions, R.Aguero et al. how-to discusses multiple
channels support only, not multiple interfaces support. The MW-Node
supports both.
Note that routing agents cannot be used directly with the MW-Node, even
in the case of a node with a single interface, and need to be converted.
Some guidelines are provided in the documentation.

Also, the layout of the MW-Node differs from the layout of a standard
MobileNode and therefore from the layout proposed by R.Aguero et al.
In the MW-Node, the routing object lies before the address classifier.
This is to enforce that data packets pass through the routing object.
This is not the case with a standard MobileNode at the destination or at
a portal (wired-wireless) node.

Finally, a new network interface object is provided and enables:
- per interface operation control (e.g. bring up/down one of two
interfaces only)
- better wired/wireless integration.

Regards,

Laurent Paquereau
Q2S Centre of Excellence, NTNU

转自:

http://mailman.isi.edu/pipermail/ns-users/2007-February/058759.html

......

[Read More...]

Aguero.C.R’s “Adding Multiple Interface Support in NS-2″

这个也是一个叫Aguero Ramon开发的多接口多信道的ns2扩展.十分不错.详细信息在pdf里:

we propose a set of changes to be done, so as to be able to use devices having multiple interfaces within the ns-2 framework. These changes and modifications are summarized in the howto “Adding Multiple Interface Support in NS-2″, which you can download from the following link.

PDF:

http://personales.unican.es/aguerocr/files/ucMultiIfacesSupport.pdf

转自:

http://personales.unican.es/aguerocr/

......

[Read More...]

“MW-Node” path for ns2 to support multiple interfaces & multiple channels

一个我最开始选用的multi-interface的扩展,不过貌似不是特别好用,现在转移用hyacinth了…XD….如下:

MW-Node patch for ns-2

A Module-based Wireless Node (MW-Node) is a Node with wireless and mobile capabilities added by means of modules. It is not a new node object derived from Node. Rather it is a new layout of mostly existing components. Rationale for this new design has been presented in [1]. The MW-Node provides a flexible support for wireless and mobile networking and in particular:

* support for multiple interfaces/multiple channels, and
* a common basis for the implementation of wireless routing protocols.

Download

Get the latest patch for ns-2.30 (patch for ns-2.29.3). Log. RSS

Install

Move to ns-2.30 directory.

If you have already installed ns run

make distclean

Patch the code and reinstall ns

patch -p1 < ns-2.30-mwnode-20070301.patch
./configure
make
chmod u+x tcl/test/test-all-mwnode

To validate the installation run

./validate

Documentation

Documentation is available in doc/mwnode.

Doxygen documentation can be generated locally by running doxygen in doc/mwnode.

Example scenario

An example scenario (mwnode-ex.tcl) is provided in tcl/ex. To run the simulation, move to tcl/ex and run

ns mwnode-ex.tcl

Reference

[1] Laurent Paquereau and Bjarne E. Helvik, “A module-based wireless node for ns-2″, in Proceedings of the first Workshop on NS2: the IP network simulator (WNS2), Pisa, Italy, 2006. [doi] (request copy)

......

[Read More...]

802.11b in NS2

本文稍微大概介绍了一下ns2里的802.11b…

Making NS-2 simulate an 802.11b link
Joshua Robinson jpr -at- rice.edu

For a research project I worked on in 2004 (resulting paper here), I used two Netgear MA311 cards to create a simple ad hoc connection. These cards are 802.11b PCI cards, stuck in the back of brand new dell workstations. I did some simple throughput tests using netperf, and found that my results differed significantly from what NS told me.

So I set about to figure out why things were different and what needed to be done to sync the results. I’ll quickly explain my findings as it wasn’t a complex process. Skip to here if you want to see my actual results.

First, I’m assuming version 2.27 or newer here. If you’re using older versions, some things will be different and I’ll try to point them out if I can.

Data Rate
NS, by default, has the data rate for the MAC set at 2 Mbps. But cards are faster now. My cards are 802.11b, which means they’re 11 Mbps, and so we need to change this. Add the following to the beginning of your simulation script:
Mac/802_11 set dataRate_ 11Mb

The card can send at 1, 2, 5.5, or 11 Mbps. Most cards support some kind of ARF (Auto-Rate Fallback) for automatic rate selection between these choices. ARF basically seems to be a slow-timescale feedback mechanism. If there are a lot of packet errors, ARF will step down the rate, and conversely, if there are no errors then the rate will be increased. I’m not explaining this in detail because NS doesn’t support any multi-rate functionality by default. That means mobile nodes will always send their packets at dataRate_. So if you really want to be realistic, you need to support this somehow. I didn’t.

RTS Threshold
Almost all commercial 802.11b cards have the RTS/CTS exchange turned off by default. This is not a bad decision since I think most people’s home wlan networks are simple enough so that the RTS/CTS really is just unnecessary overhead. NS by default has this feature turned on, so we probably want to tell NS not to use this feature. Add this line to the beginning of your script:
Mac/802_11 set RTSThreshold_ 3000

This means that an RTS will only be sent for packets that are bigger than 3000 bytes, which should be never. Note: if you want RTS/CTS on, then set this value to zero.

Preamble
I think this is probably the least obvious modification so I’ll try to be a little more detailed. Every packet is sent with a preamble, which is just a known pattern of bits at the beginning of the packet so that the receiver can sync up and be ready for the real data. This preamble must be sent at the basic rate (1 Mbps), according to the official standard. But there are two different kinds of preambles, short and long - referring to the length of the sync field. The long preamble has a field size of 128 bits, while the short preamble is only 56 bits. I would guess this short preamble option came about as hardware progressed and transceivers got better at locking on to a signal. NS is set by default to use the long preamble. My cards use the short preamble by default, and unfortunately, I don’t know a good way to determine if your card is using long or short preambles. Email me if you have any ideas.

To support short preambles in NS, add the following line at the beginning of your script:
Mac/802_11 set PreambleLength_ 72
Note: there are 16 other bits in the preamble that aren’t affected by the short/long distinction. To go back to long, change this value to 144.

The Channel
Above is everything you need to simulate an 802.11b card accurately (at least more accurately than the default NS does), but there’s still a big assumption in NS - that’s the wireless channel model. Currently the received power of a packet only depends on the distance between sender and receiver. But in real life, there are a lot of other factors influencing received power. And if you want a realistic simulation, you need to simulate this. I would suggest going here to find out more information about a more realistic channel fading model.

Packet Size
There is a slightly annoying default setting in many versions of ns that makes your packet size not what you think it is. The default setting is this:
Agent/UDP set packetSize_ 1000
Which means that if you try to set your UDP packet size to greater than this, it will actually split up each packet into two smaller ones. You really want this line:
Agent/UDP set packetSize_ 1500
If you are not sure if this is a problem, I would recommend checking the packet sizes in your trace file. If you see the wrong packet sizes, this is most likely the problem.

Results
The table below shows achieved UDP throughput in Mbps.

Packet Size (Bytes)

Simulation
RTS off
Experimental
RTS off
Simulation
RTS on
Experimental
RTS on

128

1.28

1.2

0.75

0.76

256

2.03

2.08

1.4

1.42

512

3.67

3.58

2.48

2.5

1024

5.49

5.38

4.03

4.05

1440

6.41

6.35

4.93

4.96


As you can see, the simulation results are very close to the real results I obtained. In fact, I believe that they are close enough so that the difference can be entirely accounted for by the randomness of the CSMA MAC.

Please send me any comments/questions/corrections. Thanks.


转自:

http://www.ece.rice.edu/~jpr/ns/docs/ns-802_11b.html#Results

......

[Read More...]

很有用的ns2的相关处理工具

1. 分析Trace

NANS
- Network Analyzer for Network Simulator ns2
--By Java
http://www.geocities.com/ankurjain009/projects.htm
NANS is the utility which brings all these features into one and from now on wards, strives to eliminate all the problem associated with it.



TRACEGRAPH - Network Simulator NS-2 trace files analyzer
--By Matlab
http://www.geocities.com/tracegraph/
Trace graph is a free network trace files analyzer developed for network simulator ns-2 trace processing. Trace graph can support any trace format if converted to its own or ns-2 trace format. Trace graph runs under Windows, Linux, UNIX and MAC OS systems. Trace converter processes traces over 80x faster and is available to buy.



jTrana
--By Java & MySQL

https://sourceforge.net/projects/jtrana/
Jtrana is a Java-based NS-2 wireless simulation trace analyzer. Its input is an NS2 wireless trace, and its output is a graph or data-set that can be plottedwith other tools such as Gnuplot.Any problem, plz visit:http://ns2trana.googlepages.com
It's from Weiwei's Study (http://hi.baidu.com/vvfang).




2. 场景制作辅助

NSG2
--By Java
http://wushoupong.googlepages.com/nsg
NS2 Scenarios Generator 2(NSG2) is a JAVA based ns2 scenarios generator. Since NSG2 is written by JAVA language, you can run NSG on any platform. NSG2 is capable of generating both wired and wireless TCL scripts for ns2. This tool provides wireless node function. Below this does not have.



NS WorkBench - Graphical User Interface For Network Simulator
--By Java
http://www.mnlab.cs.depaul.edu/projects/nsbench/
nsBench makes NS-2 simulation development and analysis faster and easier for students and researchers without losing the flexibility or expressiveness gained by writing a script.



(待续...)

......

[Read More...]

TeNS:The Enhanced Network Simulator (TeNs), for multi-interface implementation

TeNS是另一个支持多信道多接口的NS2的扩展.比Hyacinth的扩展性要强,自由度高.但是貌似支持的ns2版本太老了...用在ns-allinone-2.1b9a-gcc32... -_-"

Features in TENS 1.2

  • Multiple interface support added

  • Static Routing implemented for wireless nodes

  • Co Channel interference added

  • Adaptive data rate support for 802.11

  • BPSK Modulation Scheme Added

  • Directional Antenna support added (More radiation pattern added in TENS1.2)

  • Channel Number made configurable

  • Addition of ARP entries through script

  • 2-p protocol for point to point link added

  • Several MAC parameters like RTS Threshold, Capture threshold made configurable.


Tutorial

In this section we provide a quick tutorial on the new feature additions and their usage. Please note that this tutorial assumes that the reader is fairly acquainted with NS-2. Extensive NS-2 tutorials can be found at the following links:


4.1 Configuring Network Components

4.2 Main Program

4.3 Configuration Of Nodes

4.3.1 Setting up Multiple interfaces

4.3.2 Attaching a directional antenna

4.3.3 Setting the Transmit Power

4.3.4 Channel Number Setting

4.3.5 Capture Threshold Setting

4.3.6 Carrier Sense Threshold Setting

4.3.7 Rx Threshold Setting

4.3.8 Modulation Scheme Settings

4.3.9 Frequency settings and Loss factor

4.4 Adding Static Routes

4.5 Setting up parameters for MAC

4.6 Adding ARP entries

4.7 Using the 2P Iimplementation

4.7.1 Link Layer Configurations

4.7.2 MAC Layer Configurations

转自
http://www.cse.iitk.ac.in/users/braman/tens/#Tutorial
......

[Read More...]

Measure acket loss rate, jitter, and end-to-end delay for UDP-based applications

Two methods will be presented. One is to parse the traffic trace file by using gawk, and the other is to insert some codes in C++ codes. The first method is easy when the simulation is only on wired network topology. When the simulation covers wireless part, using gawk to parse traffic trace file becomes hard. Because the trace format for wireless is not the same. However, the second method needs some efforts before using it. But if the work is done, it will be easy for you to get these metrics despite wireless or wired simulation scenarios.

Method.1 Parsing the trace file (skipped)

Method.2 Modify and add mudp&mudpsink


The basic idea is to insert two fields, sendtime_ and pkt_id_, in the hdr_cmn header. When packets are sent, the packet id and send time is recorded in the sender trace file. Then when packets are received at the destination, the packet id and receiving time is recorded in the receiver trace file. So I prepare two agents, mudp and mudpsink to do the jobs. Mudp is the extension of udp agent. It only overrides the sendmsg function to keep download the packet id and sendtime in the user specified file.

[Insert the codes into NS2]

1.Download mudp.cc, mudp.h, mudpsink.cc, and mudpsink.h.
2.Create a folder named measure under ns. (for example, ~/ns-allinone-2.28/ns-2.28/measure)
3.Put these four files into measure folder.
4.Add sendtime_, pkt_id_ into packet common header. (modify common/packet.h)

struct hdr_cmn {
enum dir_t { DOWN= -1, NONE= 0, UP= 1 };
packet_t ptype_; // packet type (see above)
int size_; // simulated packet size
int uid_; // unique id
int error_; // error flag
int errbitcnt_; // # of corrupted bits jahn
int fecsize_;
double ts_; // timestamp: for q-delay measurement
int iface_; // receiving interface (label)
dir_t direction_; // direction: 0=none, 1=up, -1=down
double sendtime_; ...
unsigned long int pkt_id_;
...
inline int& addr_type() { return (addr_type_); }
inline int& num_forwards() { return (num_forwards_); }
inline int& opt_num_forwards() { return (opt_num_forwards_); }
//monarch_end
inline double& sendtime() { return (sendtime_); } // added by smallko
}

5.Add the “measure/mudp.o measure/mudpsink.o “ in the OBJ_CC of Makefile.
6.Add “Agent/mUDP set packetSize_ 1000” in the ns-default.tcl. (ns-default.tcl is under ~/ns-allinone-2.28/ns-2.28/tcl/lib)
7.make clean ; make

Then in tcl file:

...
#Setup a mUDP connection
set udp [new Agent/mUDP]
#set the sender trace file name (sd)
$udp set_filename sd
$ns attach-agent $n1 $udp
set null [new Agent/mUdpSink]
#set the receiver trace file name (rd)
$null set_filename rd
$ns attach-agent $n3 $null
$ns connect $udp $null
$udp set fid_ 2

#Setup a CBR over UDP connection
set cbr [new Application/Traffic/CBR]
$cbr attach-agent $udp
$cbr set type_ CBR
$cbr set packet_size_ 1000
$cbr set rate_ 1mb
$cbr set random_ false
...

After running, you will get sd and rd.

(sd)

0 0.100000
1 0.108000
2 0.116000
3 0.124000

……………………………….

The first column: packet id ; the second column: packet send time

(rd)

0 0.100000 0.138706 0.038706
1 0.108000 0.146706 0.038706
2 0.116000 0.154706 0.038706

……………………………………………………………………………

The first column: packet id ; the second column: packet send time; the third column: packet receiving time; the fourth column: end-to-end delay.


转自
http://140.116.72.80/~smallko/ns2/tool_en.htm

补充:还有另外2个连接讲述类似诶内容,统计相关数据的
http://hpds.ee.ncku.edu.tw/~smallko/ns2/wireless-udp-1.htm 针对udp
http://140.116.72.80/~smallko/ns2/tool.htm (中文)针对用awk来统计ns2的trace各类数据以及制图
......

[Read More...]

Propagation Threshold calculation

在ns-2.29/indep-utils/propagation/threshold.cc內可以得知,FreeSpace與TwoRayGround兩種model計算Pr的方式:

double TwoRay(double Pt, double Gt, double Gr, double ht, double hr, double L, double d, double lambda)
{
/*
* if d <>= crossover_dist, use two ray model
*
* Two-ray ground reflection model.
*
* Pt * Gt * Gr * (ht^2 * hr^2)
* Pr = ----------------------------
* d^4 * L
*
* The original equation in Rappaport's book assumes L = 1.
* To be consistant with the free space equation, L is added here.
*/

double Pr; // received power
double crossover_dist = (4 * M_PI * ht * hr) / lambda;

if (d < pr =" Friis(Pt," pr =" Pt">

Pr:在程式中即為RXThresh_也就是要在tcl所設定的數值
Pt = transmit power
Gt = transmit antenna gain
Gr = receive antenna gain
ht = transmit antenna height
hr = receive antenna height
d = distance (例如250m)

根據網路上鎖參考的資料,我們可以透過編譯threshold.cc來產生一個執行檔,再經由輸入相對應的參數至所產生的執行檔,即可得到RXThresh_,以下敘述如何產生出RXThresh_:

Step1.
ns-2.29/indep-utils/propagation/ 執行以下的編譯指令:
$g++ threshold.cc -o calculate

Step2.
若要執行計算某distance其相對應的RXThresh_,則執行以下指令:

$./calculate -m TwoRayGround -fr 3.5e+9 250

(計算model為TwoRayGround,且frequency為3.5MHz,距離250M)
如此即可計算出RXThresh_ .
......

[Read More...]

NS2里的CSThresh,RXThresh,Pr等等的意义...

学习802.11的载波侦听机制,其实最重要的是了解 Physical Carrier Sense和Virtual Carrier Sense的不同,另外,NS-2里如何控制一个包能不能被接收到,能不能产生干扰的机制,也就是那几个关键的控制数值,如 CSThresh,RXThresh,Pr等等。这里解释一下:

1. 如果Pr < CSThresh,那么无线网络接口将这个信号作为噪声而丢弃。
因此,MAC 层不能检测到这个载波。或者说,对于MAC 层而言,这个信
号是不存在的。
2. 如果CSThresh < Pr < RXThresh,无线网络接口将这个信号标记为错
误信号,然后上传给MAC 层进行处理。对于MAC 层而言,该信号可以
被检测到,但是不能被正确地解码。因此,MAC 层将该信号视为一个干
扰噪声。
3. 如果Pr > RXThresh,无线网络接口直接将该信号上传给MAC 层。此
时, MAC 层可以对该信号进行正确地解码,并进行相应地处理。

在NS-2 仿真软件中,干扰范围的半径约为发射范围半径的2.2 倍。

转自
http://hi.baidu.com/vvfang/blog/item/bf834c0fc3b4ab296159f344.html
......

[Read More...]

NS-MIRACLE: Multi-InteRfAce Cross-Layer Extension library for the NS2

一个Multi-Interface的扩展,没用过,回头用用看 ; )

Overview


NS-MIRACLE is a set of libraries designed to enhance the functionalities provided by the Network Simulator ns2. It provides an efficient and embedded engine for handling cross-layer messages and, at the same time, enables the co-existance of multiple modules within each layer of the protocol stack. For instance, multiple IP, link layers, MACs or physical layers can be specified and used within the same node. The NS-MIRACLE framework facilitates the implementation and the simulation of modern communication systems in ns2; moreover, due to its modularity, the code will be portable, re-usable and extensible. (Download)

Installation

For step-by-step installation instructions, you can refer to the nsmiracle-dei80211mr tutorial.

Documentation

A detailed documentation of ns-miracle is available. Please note that this documentation was written for a preliminary release of ns-miracle, and is therefore somehow outdated.

You can find the documentation here.

In this release, in addition to MIRACLE library, it is included a set of libraries to simulate wireless system networks, in detail:
  • Traffic generators
  • TCP Agents
  • IP modules
  • IEEE802.11 (both the one from standard ns distribution and Multirate [2])
  • MPhy, a general physical layer module in which interference of
  • in-flight packets is evaluated using a Gaussian Model, and an enhanced
  • propagation model is provided (fading with Jakes Simulator, shadowing
  • with Gudmonson model and path loss with Hata model)
  • UMTS:
    • Link layer is derived from eurane extension [3]
    • Physical layer is develpoed exteding Mphy
    • Link and Wireless Channel
    • physical mobility models (standard and Gauss Markov mobility model)
转自
http://www.dei.unipd.it/wdyn/?IDsezione=3965
......

[Read More...]

2008年7月5日星期六

著名UIUC的WirelessLab共享的ns2练习课

Wireless Networking: ns2 Laboratory Exercises

Table of Contents

Lab 101: Introduction to ns2

Lab 102: MAC Contention Window

Lab 103: 802.11 Carrier-Sense

Lab 104: 802.11 Fairness

Lab 105: Data Throughput

Lab 106: Rate Control

Lab 107: RF Propagation Models in ns2

Lab 108: Probabilistic Broadcast

Lab 109: Adhoc Routing - DSDV

Lab 110: On-demand Routing Protocols

Lab 111: Application Control and Queue Management

Lab 112: Back-Pressure Scheduling

Lab c101: MAC Contention Window and RTS (lab 102 with an additional part)

Lab c102: 802.11 Fairness and Comparison of DSR and AODV Routing Protocols (combo of labs 104 and 110)



http://www.crhc.uiuc.edu/wireless/assignments/simulations/
......

[Read More...]

无意翻到的而一个人关于NS2的Q&A,有十几个小问答

这是无意翻到的而一个人的Q&A,有点小内容摘抄下.~;_)
http://web.syr.edu/~dchen02/FAQ.txt

包含如下的小问题:

Scheduler:: Event UID not valid!

What is the role of GOD?

How to debug my extension to ns2?

Difference between Thresholds in wireless-phy.cc

What does it mean when ns gives the message "scheduler going backwards from 73.9587457845 to -1417846817.3257839 ?

How to set up the wireless bandwidth (such as 802.11 a,b,g) in NS2?

When do we need to "make clean; make depend; make" in ns2?

How to deal with Very large trace files?

How to disable RTS/CTS?

What is size of voice or data packet size used to simulate in a wireless LAN?

How to run a set of similar experiments together?

Rx Power or carrier sense Threshold setting?

How to pass an argument from tcl to c++?

How to post analyze the trace file?

How to disable the routing when you wanna measure MAC layer performance?

How to use parameters in command line?

How to debug by printf?



转自
http://web.syr.edu/~dchen02/FAQ.txt
......

[Read More...]

Measure the throughput of TCP-based application

TCP流量的取得,先修改添加tcpsink,然后用perl脚本对tcpsink的trace进行分析:
如下:

[Preparation for tcpsink]

1. Follow the steps of method2 at http://140.116.72.80/~smallko/ns2/tool_en.htm
2. Download mtcpsink.cc, mtcpsink.h
3. Put these two files into measure folder
4. Add the “measure/mtcpsink.o” in the OBJ_CC of Makefile
5. make clean; make

In tcl file:

...
set tcp1 [new Agent/TCP/Reno]
$ns attach-agent $s1 $tcp1
set tcpsink1 [new Agent/TCPSink/mTcpSink]
$tcpsink1 set_filename tcp_sink
$ns attach-agent $wl_node_(0) $tcpsink1
$ns connect $tcp1 $tcpsink1
set ftp1 [$tcp1 attach-source FTP]
....

After running the script, you will get “tcp_sink”.

...
4 0.013904 1040
5 0.015277 1040
6 0.016750 1040
...

[use perl to calculate the throughput] (throughput.pl)

#使用方法: perl throughput.pl

#記錄檔檔名
$infile=$ARGV[0];

#多少時間計算一次(單位為秒)
$granularity=$ARGV[1];

$sum=0;
$sum_total=0;
$clock=0;
$init=0;

#打開記錄檔
open (DATA,"<$infile") die "Can't open $infile $!"; #讀取記錄檔中的每行資料,資料是以空白分成眾多欄位 while () {
@x = split(' ');

if($init==0){
$start=$x[1];
$init=1;
}

#讀取的第一個欄位是時間
#判斷所讀到的時間,是否已經達到要統計吞吐量的時候
if ($x[1]-$clock <= $granularity) { #計算單位時間內累積的封包大小 $sum=$sum+$x[2]; #計算累積的總封包大小 $sum_total=$sum_total+$x[2]; } else { #計算吞吐量 $throughput=$sum*8.0/$granularity; #輸出結果: 時間 吞吐量(bps) print STDOUT "$x[1]: $throughput bps\n"; #設定下次要計算吞吐量的時間 $clock=$clock+$granularity; #計算單位時間內累積的封包大小 $sum=$sum+$x[1]; #把累積量規零 $sum=0; } } $endtime=$x[1]; #計算最後一次的吞吐量大小 $throughput=$sum*8.0/$granularity; print STDOUT "$x[1]: $throughput bps\n"; $clock=$clock+$granularity; $sum=0; #print STDOUT "$sum_total $start $endtime\n"; $avgrate=$sum_total*8.0/($endtime-$start); print STDOUT "Average rate: $avgrate bps\n"; #關閉檔案 close DATA; exit(0); Each 1 second, we calculate the TCP throughput. $perl throughput.pl tcp.sink 1.0 …………………………………………………………………………………… 42.003966: 3502720 bps 43.000810: 3452800 bps 44.001948: 3452800 bps 45.001001: 3494400 bps 45.026674: 83200 bps Average rate: 3463041.26872255 bps


转自
http://140.116.72.80/~smallko/ns2/measure_tcp.htm
......

[Read More...]

Get the system throughput for UDP-based application

非常有用的很直接能看到flow的throughput的修改.利用loss-monitor,记录第一个包和最后一个包的抵达时间,然后计算出流量. 用于UDP.

A. Modification:

1. Modify the tools/loss-monitor.h

class LossMonitor : public Agent {
public:
LossMonitor();
virtual int command(int argc, const char*const* argv);
virtual void recv(Packet* pkt, Handler*);
protected:
int nlost_;
int npkts_;
int expected_;
int bytes_;
int seqno_;
double last_packet_time_;
//add the following two lines
double first_packet_time_;
int first;

};

2. Modify the tools/loss-monitor.cc

LossMonitor::LossMonitor() : Agent(PT_NTYPE)
{
bytes_ = 0;
nlost_ = 0;
npkts_ = 0;
expected_ = -1;
last_packet_time_ = 0.;
first_packet_time_ = 0.;
first=0;

seqno_ = 0;
bind("nlost_", &nlost_);
bind("npkts_", &npkts_);
bind("bytes_", &bytes_);
bind("lastPktTime_", &last_packet_time_);
bind("firstPktTime_", &first_packet_time_);
bind("expected_", &expected_);
}

void LossMonitor::recv(Packet* pkt, Handler*)
{
hdr_rtp* p = hdr_rtp::access(pkt);
seqno_ = p->seqno();
bytes_ += hdr_cmn::access(pkt)->size();
++npkts_;
if(first==0){
first_packet_time_=Scheduler::instance().clock();
first=1;
}

3. Recompile

cd ns.../ns...; make clean; make

B. Usage

In NS2 tcl file:

Modify each end null agent of udp traffic as a LossMonitor agent

set udp_($i) [new Agent/UDP]
$ns_ attach-agent $node_($i) $udp_($i)
set null_($i) [new Agent/LossMonitor]
$ns_ attach-agent $node_($i) $null_($i)

And by the end of the tcl: add "record" procedure:

$ns_ at 4.9 "record"
proc record {} {
global ns_ null_ val
set sum 0
###Add more, one by one###
set i 0
set th 0
set a [$null_($i) set bytes_]
set b [$null_($i) set lastPktTime_]
set c [$null_($i) set firstPktTime_]
set d [$null_($i) set npkts_]
if {$b>$c} {
set th [expr ($a-$d*20)*8/($b-$c)]
puts "flow $i has $th bps while working time"
}
set sum [expr $sum+$th]
###Add more, one by one###
puts "total throughput:$sum bps"
}

Then, we can see the udp throughput by the end of simulation.. : )

转自
http://140.116.72.80/~smallko/ns2/total_throghput.htm

......

[Read More...]