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

📄 agents.tex

📁 柯老师网站上找到的
💻 TEX
📖 第 1 页 / 共 3 页
字号:
                Packet::free(pkt);        \}        void TcpSink::ack(Packet* opkt)        \{                Packet* npkt = allocpkt();                        hdr_tcp *otcp = (hdr_tcp*)opkt->access(off_tcp_);                hdr_tcp *ntcp = (hdr_tcp*)npkt->access(off_tcp_);                ntcp->seqno() = acker_->Seqno();                ntcp->ts() = otcp->ts();                        hdr_ip* oip = (hdr_ip*)opkt->access(off_ip_);                hdr_ip* nip = (hdr_ip*)npkt->access(off_ip_);                nip->flowid() = oip->flowid();                        hdr_flags* of = (hdr_flags*)opkt->access(off_flags_);                hdr_flags* nf = (hdr_flags*)npkt->access(off_flags_);                nf->ecn_ = of->ecn_;                        acker_->append_ack((hdr_cmn*)npkt->access(off_cmn_),                                   ntcp, otcp->seqno());                send(npkt, 0);        \}\end{program}The \fcn[]{recv} method overrides the \fcn[]{Agent::recv} method(which merely discards the received packet).It updates some internal state with the sequence number of thereceived packet (and therefore requires the \code{off_tcp_} variableto be properly initialized.It then generates an acknowledgment for the received packet.The \fcn[]{ack} method makes liberal use of access to packet headerfields including separate accesses to the TCP header, IP header,Flags header, and common header.The call to \fcn[]{send} invokes the \fcn[]{Connector::send} method.\subsection{Processing Responses at the Sender}\label{sec:tcpsimpleack}Once the simple TCP's peer receives data and generates an ACK, thesender must (usually) process the ACK.In the \code{TcpAgent} agent, this is done as follows:\begin{program}        /*         * {\cf main reception path - should only see acks, otherwise the}         * {\cf network connections are misconfigured}         */        void TcpAgent::recv(Packet *pkt, Handler*)        \{                hdr_tcp *tcph = (hdr_tcp*)pkt->access(off_tcp_);                hdr_ip* iph = (hdr_ip*)pkt->access(off_ip_);                ...                if (((hdr_flags*)pkt->access(off_flags_))->ecn_)                        quench(1);                if (tcph->seqno() > last_ack_) \{                        newack(pkt);                        opencwnd();                \} else if (tcph->seqno() == last_ack_) \{                        if (++dupacks_ == NUMDUPACKS) \{                                \ldots                        \}                \}                Packet::free(pkt);                send(0, 0, maxburst_);       \}\end{program}This routine is invoked when an ACK arrives at the sender.In this case, once the information in the ACK is processed (by \code{newack})the packet is no longer needed and is returned to the packet memoryallocator.In addition, the receipt of the ACK indicates the possibility of sendingadditional data, so the \fcn[]{TcpSimpleAgent::send} method isinvoked which attempts to send more data if the TCP window allows.\subsection{Implementing Timers}\label{sec:tcptimer}As described in \href{the following chapter}{Chapter}{chap:timers}, specifictimer classes must be derived from an abstract base\clsref{TimerHandler}{../ns-2/timer-handler.h}defined in \nsf{timer-handler.h}.  Instances of thesesubclasses can then be used as various agent timers.An agent may wish to override the \fcn[]{Agent::timeout} method(which does nothing).In the case of the Tahoe TCP agent, two timers are used:a delayed send timer \code{delsnd_timer_} and a retransmission timer \code{rtx_timer_}.\href{We describe the retransmission timer in TCP}{Section}{sec:timerexample}as an example of timer usage.  \section{Creating a New Agent}\label{sec:createagent}To create a new agent, one has to do the following:\begin{enumerate}\itemsep0pt        \item \href{decide its inheritance structure}{Section}{sec:pingexample},                and create the appropriate class definitions,        \item \href{define the \fcn[]{recv} and \fcn[]{timeout} methods}{%                Section}{sec:agents:exmethods},        \item define any necessary timer classes,        \item \href{define OTcl linkage functions}{Section}{sec:agents:exlinkage},        \item \href{write the necessary OTcl code to access the agent}{Section}{sec:agents:exotclcode}.\end{enumerate}The action required to create and agent can be illustratedby means of a very simple example.Suppose we wish to construct an agent which performsthe ICMP ECHO REQUEST/REPLY (or ``ping'') operations.\subsection{Example: A ``ping'' requestor (Inheritance Structure)}\label{sec:pingexample}Deciding on the inheritance structure is a matter of personal choice, but islikely to be related to the layer at which the agent will operateand its assumptions on lower layer functionality.The simplest type of Agent, connectionless datagram-oriented transport, isthe \code{Agent/UDP} base class.  Traffic generators can easily be connectedto UDP Agents.For protocols wishing to use a connection-oriented stream transport(like TCP), the various TCP Agents could be used.Finally, if a new transport or ``sub-transport'' protocolis to be developed, using \code{Agent}as the base class would likely be the best choice.In our example, we'll use Agent as the base class, given thatwe are constructing an agent logically belonging to the IP layer(or just above it).We may use the following class definitions:\begin{program}        class ECHO_Timer;         class ECHO_Agent : public Agent \{         public:                ECHO_Agent();                int command(int argc, const char*const* argv);         protected:                void timeout(int);                void sendit();                double interval_;                ECHO_Timer echo_timer_;        \};        class ECHO_Timer : public TimerHandler \{        public:                ECHO_Timer(ECHO_Agent *a) : TimerHandler() \{ a_ = a; \}        protected:                virtual void expire(Event *e);                ECHO_Agent *a_;        \}; \end{program}\subsection{The \texttt{recv}() and \texttt{timeout}() Methods}\label{sec:agents:exmethods}The \fcn[]{recv} method is not defined here, as this agentrepresents a request function and will generally not be receivingevents or packets\footnote{This is perhaps unrealistically simple.An ICMP ECHO REQUEST agent would likely wish to processECHO REPLY messages.}.By not defining the \fcn[]{recv} method, the base class versionof \fcn[]{recv} (\ie, \fcn[]{Connector::recv}) is used.The \fcn[]{timeout} method is used to periodically send request packets.The following \fcn[]{timeout} method is used, along with a helpermethod, \fcn[]{sendit}:\begin{program}        void ECHO_Agent::timeout(int)        \{                sendit();                echo_timer_.resched(interval_);        \}        void ECHO_Agent::sendit()        \{                Packet* p = allocpkt();                ECHOHeader *eh = ECHOHeader::access(p->bits());                eh->timestamp() = Scheduler::instance().clock();                send(p, 0);     // {\cf Connector::send()}        \}        void ECHO_Timer::expire(Event *e)        \{                a_->timeout(0);        \}\end{program}The \fcn[]{timeout} method simply arranges for \fcn[]{sendit} to beexecuted every \code{interval_} seconds.The \fcn[]{sendit} method creates a new packet with most of itsheader fields already set up by \fcn[]{allocpkt}.The packet is only lacks the current time stamp. The call to \fcn[]{access} provides for a structured interface to thepacket header fields, and is used to set the timestamp field.Note that this agent uses its own special header (``ECHOHeader'').The \href{creation and use of packet headers is described inlater chapter}{Chapter}{chap:pformat};to send the packet to the next downstream node, \fcn[]{Connector::send}is invoked without a handler.\subsection{Linking the ``ping'' Agent with OTcl}\label{sec:agents:exlinkage}We have the \href{methods and mechanisms for establishing OTcl Linkage earlier}{%        Chapter}{chap:otcl:intro}.This section is a brief review of the essential features of thatearlier chapter, and describes the minimum functionality required to create the ping agent.There are three items we must handle to properly link our agentwith Otcl.First we need to establish a mapping between the OTcl namefor our class and the actual object created when aninstantiation of the class is requested in OTcl.This is done as follows:\begin{program}        static class ECHOClass : public TclClass \{        public:                ECHOClass() : TclClass("Agent/ECHO") \{\}                TclObject* create(int argc, const char*const* argv) \{                        return (new ECHO_Agent());                \}        \} class_echo;\end{program}Here, a {\em static} object ``class\_echo'' is created. It's constructor(executed immediately when the simulator is executed) places the class name``Agent/ECHO'' into the OTcl name space.The mixing of case is by convention;recall from Section~\ref{sec:TclClass} in the earlier chapters thatthe ``/'' character is a hierarchy delimiter for the interpreted hierarchy.The definition of the \fcn[]{create} method specifies how a C++shadow object should be created whenthe OTcl interpreter is instructed to create anobject of class ``Agent/ECHO''.  In this case, a dynamically-allocatedobject is returned.  This is the normal way new C++ shadow objectsare created.% Note that arguments could have been passed to our constructor% via OTcl through the conventional \code{argc/argv} pairs of the% \fcn[]{create} method, although this is rare.Once we have the object creation set up, we will want to linkC++ member variables with corresponding variables in the OTclnname space, so that accesses to OTcl variables are actuallybacked by member variables in C++.Assume we would like OTcl to be able to adjust the sendinginterval and the packet size.This is accomplished in the class's constructor:\begin{program}        ECHO_Agent::ECHO_Agent() : Agent(PT_ECHO)        \{                bind_time("interval_", &interval_);                bind("packetSize_", &size_);        \}\end{program}Here, the C++ variables \code{interval_} and \code{size_} arelinked to the OTcl instance variables \code{interval_} and\code{packetSize_}, respectively.Any read or modify operation to the Otcl variables will resultin a corresponding access to the underlying C++ variables.The \href{details of the \fcn[]{bind} methods are described elsewhere}{%        Section}{sec:VarBinds}.The defined constant \code{PT_ECHO} is passed to the \fcn[]{Agent}constuctor so that the \fcn[]{Agent::allocpkt} method may setthe \href{packet type field used by the trace support}{%        Section}{sec:traceptype}.In this case, \code{PT_ECHO} \href{represents a new packet type and must be defined in \nsf{trace.h}}{%        Section}{sec:traceformat}.Once object creation and variable binding is set up, we maywant to \href{create methods implemented in C++ but which canbe invoked from OTcl}{Section}{sec:Commands}.These are often control functions that initiate, terminate ormodify behavior.In our present example, we may wish to be able to start theping query agent from OTcl using a ``start'' directive.This may be implemented as follows:\begin{program}        int ECHO_Agent::command(int argc, const char*const* argv)        \{                if (argc == 2) \{                        if (strcmp(argv[1], "start") == 0) \{                                timeout(0);                                return (TCL_OK);                        \}                \}                return (Agent::command(argc, argv));        \}\end{program}Here, the \fcn[]{start} method available to OTcl simply callsthe C++ member function \fcn[]{timeout} which initiates thefirst packet generation and schedules the next.Note this class is so simple it does not even include away to be stopped.\subsection{Using the agent through OTcl}\label{sec:agents:exotclcode}The agent we have created will have to be instantiated and attachedto a node.Note that a node and simulator object is assumed to havealready been created.% (Section \ref{tcllink} describes how this is done).The following OTcl code performs these functions:\begin{program}        set echoagent [new Agent/ECHO]        $simulator attach-agent $node $echoagent\end{program}To set the interval and packet size, and start packet generation,the following OTcl code is executed:\begin{program}        $echoagent set dst_ $dest        $echoagent set fid_ 0        $echoagent set prio_ 0        $echoagent set flags_ 0        $echoagent set interval_ 1.5        $echoagent set packetSize_ 1024        $echoagent start\end{program}This will cause our agent to generate one 1024-byte packet destined fornode \code{$dest} every 1.5 seconds.\section{The Agent API}\label{sec:agents:api}Simulated applications may be implemented on top of protocol agents.  Chapter\ref{chap:applications} describes the API used by applications to  access the services provided by the protocol agent.\section{Different agent objects}\label{sec:agentobjects}Class Agent forms the base class from which different types of objectslike Nullobject, TCP etc are derived. The methods for Agent class aredescribed in the next section. Configuration parameters for:\begin{description}\item[fid\_] Flowid.\item[prio\_] Priority. \item[agent\_addr\_] Address of this agent. \item[agent\_port\_] Port adress of this agent. \item[dst\_addr\_ ] Destination address for the agent.\item[dst\_port\_] Destination port address for the agent.\item[flags\_]\item[ttl\_] TTL defaults to 32.\end{description}There are no state variables specific to the generic agent class. Otherobjects derived from Agent are given below:\begin{description}\item[Null Objects]

⌨️ 快捷键说明

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