⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ns-rca.tcl

📁 可以在ns-2中进行仿真的SPIN路由协议的源码
💻 TCL
📖 第 1 页 / 共 2 页
字号:
# Message Type Constantsset ADV 0set REQ 1set DATA 2set RESEND 3set MAC_BROADCAST 0xffffffffset LINK_BROADCAST 0xffffffffClass Application/RCApp -superclass Application############################################################################## Miscellaneous functions############################################################################## RcApp::init## This function initializes the application and all variables associated# with it.set index 0Application/RCApp instproc init {md_class wantslist haslist} {    global hasarray index    $self instvar packetMsg_    $self instvar stats_    $self instvar adv_threshold_    $self instvar pending_delay_    $self instvar rng_     $self instvar has_ wants_ pending_ md_class_ 		$self instvar advlist_    $self instvar neighbors_    $self instvar init_wants_    $self instvar advert_period_    $self instvar already_sent_data_    $self instvar resend_timeout_    # initilizations    set md_class_ $md_class    set has_ [new $md_class]    $has_ addlist $haslist    set wants_ [new $md_class]    $wants_ addlist $wantslist    set init_wants_ [$wants_ copy]    set pending_ [new $md_class]    set advlist_ [new Advlist]    set already_sent_data_ [new $md_class]    set resend_timeout_ .2    $wants_ subtract $has_    set hasarray($index) $has_    incr index    set stats_ [new RCStats]    set packetMsg_ 0    set adv_threshold_ 0    set pending_delay_ .4    set advert_period_ .4    set neighbors_ [new Set/KeySet]    set rng_ [new RNG]    $rng_ seed 0    $self next}# RcApp::getER## This function returns the EnergyResource # Application/RCApp instproc getER {} {    set er [[[$self agent] set node_] getER]    return $er}# RcApp::log## Send a comment to the log# Application/RCApp instproc log {msg} {    [$self agent] log $msg}# RcApp::log-acquired## Send a comment to the log# Application/RCApp instproc log-acquired {has} {    $self instvar init_wants_    set id [[[$self agent] set node_] id]    set hassize [$has maptosize]    set wantssize [$init_wants_ maptosize]    if {$wantssize} {		set percent [expr ($hassize + 0.0)  / $wantssize]    } else {		set percent 0    }    set msg "$id has = $percent"    $self log $msg}# RcApp::start## This function will start data exchanges between the nodes# Application/RCApp instproc start {} {    global ADV DATA MAC_BROADCAST LINK_BROADCAST ns_    $self instvar has_ adv_threshold_ advert_id_ advert_period_    # Decide whether have enough energy to ADV data     # Note: if data is ADV'd, node must send the data    set adv_meta [$self decideADV $has_]    if {![$adv_meta emptyset?]} {		set datasize [$adv_meta maptosize]	    		set copy_meta [$adv_meta copy]		if {$datasize <= $adv_threshold_} {	   		$self send $MAC_BROADCAST $LINK_BROADCAST $DATA $copy_meta $datasize		} else {	    	$self send_meta $MAC_BROADCAST $LINK_BROADCAST $ADV $copy_meta		}    } else {		set nodeID [[[$self agent] set node_] id]		puts "Node $nodeID decided NOT to ADV has_ = [$has_ metatostring]"    }    $adv_meta destroy    return}# RcApp::stop## This function stops data exchanges between the nodes# Application/RCApp instproc stop {} {    puts "Stopping RCApp..."    [$self agent] close}############################################################################## Receiving functions############################################################################## RcApp::recv## This function handles packets.  It picks out the packet header,# and dispatches to other functions, based on the type of the message.# Application/RCApp instproc recv {args}  {    global ADV REQ DATA RESEND ns_ opt        $self instvar md_class_ stats_ neighbors_ rng_ advlist_ has_    if {[llength $args] < 2} {		puts "Error:  RCApp receive function called with too few args"		return    }    # Get the size and the string out of the arg list    set link_dst [lindex $args 0]    set sender [lindex $args 1]    set data_size [lindex $args 2]    set meta_string [lrange $args 3 end]    # Add the sender to the list of known neighbors    $neighbors_ add $sender     # The type is stored internally    set msg_type [[$self agent] set packetMsg_]    # Convert the meta-data string into a data-structure    set meta_data [new $md_class_]    $meta_data stringtometa $meta_string    set nodeID [[[$self agent] set node_] id]    set senderID $sender    set msg [lindex [list ADV REQ DATA RESEND] $msg_type]    puts "\nNode $nodeID received $msg ($meta_string) from Node $senderID to $link_dst. Data size is $data_size."    $neighbors_ pp "Neighbors now"    # Dispatch based on type    if {$msg_type == $ADV} {		# Add meta_data and sender to advlist_		# This list keeps track of ADVs and who sent the ADV.  O/w  		# could get an REQ for data which this node cannot receive b/c		# it is outside the transmission area of the sending node, e.g.:		# A  -->  B       C : A sends ADV, but only B hears		# A  <--  B  -->  C : B sends REQ, both A and C hear REQ		# A  -->  B       C : A sends DATA, but only B hears		# In this situation, C should not place meta-data REQd by B 		# on pending list, since data will not be heard by C!		$advlist_ addADV $sender $meta_data		if {[$meta_data subset $has_]} {		    # We do nothing		    puts "\n Node $nodeID already has advertised data. We do nothing."		    $meta_data destroy		    return		}	    		# There is a 3 ms delay between sending and receiving an REQ		# Waiting time should be R=N*D to achieve E[dup] = 1		set D 3		set N [$self count_duplicates $meta_data]		if {$N < 3} {		    set N 5		}		set delay_bound [expr $D * $N]		set delay [$rng_ uniform 0 $delay_bound]		set delay_ms [expr $delay * .001]		set random_delay [expr [$ns_ now] + $delay_ms]    	$ns_ at $random_delay "$self recvADV $link_dst $sender $meta_data"    } elseif {$msg_type == $REQ} {		$self recvREQ $link_dst $sender $meta_data    } elseif {$msg_type == $RESEND} {		$self recvRESEND $sender $meta_data    } elseif {$msg_type == $DATA} {		$self recvDATA $link_dst $sender $meta_data $data_size    }}# RcApp::recvADV ## This function handles an ADV message.  It updates# "wants" using the received meta-data.  It then sends out a request# based on the intersection of "wants" and the advertisement.  This# function takes care of freeing the meta-data by freeing the data# itself, or calling another function that frees the meta-data.Application/RCApp instproc recvADV {link_dst sender meta_data} {    global ns_ REQ ADV MAC_BROADCAST     $self instvar wants_ has_ stats_ pending_ pending_delay_    set nodeID [[[$self agent] set node_] id]    puts "Node $nodeID recvADV $link_dst $sender [$meta_data metatostring]: at [$ns_ now]"    $stats_ update_rcvs $sender $ADV [$meta_data numelements] 0puts "meta-data = [$meta_data metatostring], pending = [$pending_ metatostring], has = [$has_ metatostring]"    #  Subtract what is already pending from the meta-data    $meta_data subtract $pending_    # Now subtract what we have out of the remaining meta-data    $meta_data subtract $has_    set finalsize [$meta_data numelements]    $stats_ update_useful $sender $ADV $finalsize 0    # If the meta-data contains_ nothing we want, stop.    if {[$meta_data emptyset?]} {		puts "Node $nodeID does not have any data to request from Node $sender"		$meta_data destroy		return    }    # Find the union of wants with the meta-data    $wants_ union $meta_data    # Decide whether to REQ data    set req_meta [$self decideREQ $meta_data]    if {![$req_meta emptyset?]} {		puts "Now sending an REQ back to $sender"		# Set this meta data to ageout from the pending list		set metastring [$req_meta metatostring]		$ns_ at [expr [$ns_ now] + $pending_delay_] "$self ageout_pending $sender \"$metastring\""		# Add the meta-data to the pending set		$pending_ union $req_meta			# Now send a request back to the sender for this meta-data		set copy_meta [$req_meta copy]		$self send_now $MAC_BROADCAST $sender $REQ $copy_meta 0     } else {		puts "Application not requesting data [$meta_data metatostring]."    }    $req_meta destroy    $meta_data destroy}# RCApp::recvREQ## This function handles an REQ message.  Map the data described in the# meta-data to actual data, and send it back to the sender using a DATA# message.  This function takes care of freeing the meta-data by freeing# the data itself, or calling another function that frees the meta-data.Application/RCApp instproc recvDirectREQ {sender meta_data} {    global DATA REQ MAC_BROADCAST LINK_BROADCAST ns_    $self instvar has_ stats_ already_sent_data_  advlist_    $self instvar pending_delay_ resend_timeout_    puts "I just received a direct request for data [$meta_data metatostring].  I've already sent: [$already_sent_data_ metatostring]."    # Figure out how much of this data we actually possess    set meta_we_have [$meta_data copy]    # Send the data if we possess it    $meta_we_have intersection $has_    if {[$meta_we_have emptyset?]} {	set nodeID [[[$self agent] set node_] id]	puts "Node $nodeID does not have data requested by Node $sender"	$meta_we_have destroy	$meta_data destroy	return    }    $meta_we_have subtract $already_sent_data_    if {[$meta_we_have emptyset?]} {		puts "We've recently sent data [$meta_we_have metatostring] requested by Node $sender.  Not sending."			$meta_data destroy		$meta_we_have destroy		return    }    # Now figure out how large a message would be if we sent it    set datasize [$meta_we_have maptosize]    set copy_meta [$meta_we_have copy]	# Keep track of what data has already been sent and do not 	# re-broadcast message 	# NOTE:  we need to add a time-out for this list!    $already_sent_data_ union $meta_we_have    set metastring [$copy_meta metatostring]    puts "Sending out data $metastring"    $ns_ at [expr [$ns_ now] + $resend_timeout_] "$self resend_timeout \"$metastring\""    $self send_now $MAC_BROADCAST $LINK_BROADCAST $DATA $copy_meta $datasize        $meta_data destroy    $meta_we_have destroy}Application/RCApp instproc recvIndirectREQ {link_dst sender meta_data} {    global DATA REQ MAC_BROADCAST LINK_BROADCAST ns_    $self instvar has_ stats_ already_sent_data_ pending_ advlist_

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -