📄 udp.cc
字号:
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- *//* * Copyright (C) Xerox Corporation 1997. All rights reserved. * * License is granted to copy, to use, and to make and to use derivative * works for research and evaluation purposes, provided that Xerox is * acknowledged in all documentation pertaining to any such copy or derivative * work. Xerox grants no other licenses expressed or implied. The Xerox trade * name should not be used in any advertising without its written permission. * * XEROX CORPORATION MAKES NO REPRESENTATIONS CONCERNING EITHER THE * MERCHANTABILITY OF THIS SOFTWARE OR THE SUITABILITY OF THIS SOFTWARE * FOR ANY PARTICULAR PURPOSE. The software is provided "as is" without * express or implied warranty of any kind. * * These notices must be retained in any copies of any part of this software. */#ifndef lintstatic const char rcsid[] = "@(#) $Header: /nfs/jade/vint/CVSROOT/ns-2/apps/udp.cc,v 1.19 2001/11/16 22:29:59 buchheim Exp $ (Xerox)";#endif#include "udp.h"#include "rtp.h"#include "random.h"#include "address.h"#include "ip.h"#include "mac/mac-802_11.h" //Yuan add#define CAPACITY 800 //1000K//#define EPSILON 0.00001//#define BETA 0#define STEP 5 static class UdpAgentClass : public TclClass {public: UdpAgentClass() : TclClass("Agent/UDP") {} TclObject* create(int, const char*const*) { return (new UdpAgent()); }} class_udp_agent;UdpAgent::UdpAgent() : Agent(PT_UDP), seqno_(-1),fseqno_(-1), timer_(this), first_time(1){ bind("packetSize_", &size_); bind("myfid_", &myfid_); bind("EPSILON", &EPSILON); bind("BETA",&BETA); rate_ = 50; //init rate 200K price_ = 0;}UdpAgent::UdpAgent(packet_t type) : Agent(type), timer_(this), first_time(1){ bind("packetSize_", &size_); bind("myfid_", &myfid_); bind("EPSILON", &EPSILON); bind("BETA",&BETA); rate_ = 50; //init rate 200K price_ = 0;}int hdr_pdp::offset_;static class PDPHeaderClass : public PacketHeaderClass {public: PDPHeaderClass() : PacketHeaderClass("PacketHeader/PDP", sizeof(hdr_pdp)) { bind_offset(&hdr_pdp::offset_); }} class_pdphdr;//Yuan addvoid UdpAgent::sendbackmsg(double price){ Packet *p; double local_time = Scheduler::instance().clock(); p = allocpkt(); struct hdr_cmn *ch = HDR_CMN(p); hdr_pdp* ph = hdr_pdp::access(p); //ch->size() = size_; ch->size() = 10; ph->rate() = -1; ph->price() = price; ph->flag() = 0; ch->timestamp() = (u_int32_t)(SAMPLERATE*local_time); ch->ptype() = PT_FEEDBACK; fseqno_++; ch->uid_ = fseqno_; p->setdata(NULL); target_->recv(p);}// put in timestamp and sequence number, even though UDP doesn't usually // have one.void UdpAgent::sendmsg(int nbytes, AppData* data, const char* flags){ double local_time = Scheduler::instance().clock(); Packet *p; if (first_time){ char filename[10]; sprintf(filename, "x%d.dat", myfid_); fd_x = fopen(filename, "w"); first_time = 0; } //Yuan change p = allocpkt(); struct hdr_cmn *ch = HDR_CMN(p); struct hdr_ip *ih = HDR_IP(p); hdr_pdp* ph = hdr_pdp::access(p); ch->size() = size_; ih->flowid() = myfid_; ph->rate() = rate_; fprintf(fd_x,"%f %f\n",local_time,rate_); ph->price() = 0; ph->flag() = 1; ch->timestamp() = (u_int32_t)(SAMPLERATE*local_time); ch->ptype() = PT_CBR; ch->prev_hop_ = LARGE_INT8; //define something seqno_++; ch->uid_ = seqno_; p->setdata(data); target_->recv(p); nextPkttime_ = next_interval(); /* schedule it */ if (nextPkttime_ > 0) timer_.resched(nextPkttime_); else{ printf("Error: nextPkettime_ <= 0 \n"); return; } //idle();}void UdpAgent::recv(Packet* pkt, Handler*){ struct hdr_cmn *ch = HDR_CMN(pkt); hdr_pdp* ph = hdr_pdp::access(pkt); if ((ch->ptype() == PT_CBR)&&(ph->flag())) { printf("F%d recv DATA price: %f, rate %f\n", myfid_, ph->price_, ph->rate()); if (fabs(ph->price() - price_)>EPSILON){// printf("** F%d recv DATA price: %f, rate %f\n", myfid_, ph->price_, ph->rate()); sendbackmsg(ph->price()); price_ = ph->price(); } } if (ch->ptype()== PT_FEEDBACK) {// printf("F%d udp recv feedback messge: seq %d price %f\n", myfid_, ch->uid_, ph->price()); if (fseqno_ < ch->uid_) { printf("** F%d udp recv feedback messge: seq %d price %f\n", myfid_, ch->uid_, ph->price()); fseqno_ = ch->uid_; rate_ = cal_rate(ph->price()); } } Packet::free(pkt);}/* * Yuan add * calculate the rate based on path-aggregated price * assume U = log x */double UdpAgent::cal_rate(double new_price){ double new_rate;//Yuan new change if (price_ == 0) price_ = new_price; else price_ = BETA*price_ + (1-BETA)*new_price; new_rate = 1/price_; //the unit is Kbps// new_rate = rate_ + STEP*(1-rate_*price_); if (new_rate <0) new_rate = 0; if (new_rate >CAPACITY) new_rate = CAPACITY; printf("F%d udp::cal_rate: price: %f, rate: %f\n",myfid_,new_price,new_rate); return new_rate;}int UdpAgent::command(int argc, const char*const* argv){ if (argc == 4) { if (strcmp(argv[1], "send") == 0) { PacketData* data = new PacketData(1 + strlen(argv[3])); strcpy((char*)data->data(), argv[3]); sendmsg(atoi(argv[2]), data); return (TCL_OK); } } else if (argc == 5) { if (strcmp(argv[1], "sendmsg") == 0) { PacketData* data = new PacketData(1 + strlen(argv[3])); strcpy((char*)data->data(), argv[3]); sendmsg(atoi(argv[2]), data, argv[4]); return (TCL_OK); } } return (Agent::command(argc, argv));}void UdpAgent::timeout(){ /* send a packet */ sendmsg(size_); //send a pkt (nbyte_ = size_)}double UdpAgent::next_interval(){ // Recompute interval in case rate_ or size_ has changes // Yuan Note fix rate_ temporally //double t = (double)(size_ << 3)/(double)(rate_*1000000); double t = (double)(size_ << 3)/(double)(rate_*1000); //the unit is Kbps return(t);}void UdpTrafficTimer::expire(Event *){ udpagent_->timeout();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -