The TcpAgent agent is started in the example when its FTP source receives the start directive at time 1.2. The start operation is an instance procedure defined on the class Application/FTPSectionsec:simapps. It is defined in ~ns/tcl/lib/ns-source.tcl as follows:
Application/FTP instproc start {} { [$self agent] send -1 }In this case, agent refers to our simple TCP agent and send -1 is analogous to sending an arbitrarily large file.
The call to send eventually results in the simple TCP sender generating packets. The following function output performs this:
void TcpAgent::output(int seqno, int reason) { Packet* p = allocpkt(); hdr_tcp *tcph = (hdr_tcp*)p-\>access(off_tcp_); double now = Scheduler::instance().clock(); tcph-\>seqno() = seqno; tcph-\>ts() = now; tcph-\>reason() = reason; Connector::send(p, 0); \ldots if (!(rtx_timer_.status() == TIMER_PENDING)) /* No timer pending. Schedule one. */ set_rtx_timer(); }Here we see an illustration of the use of the []Agent::allocpkt method. This output routine first allocates a new packet (with its common and IP headers already filled in), but then must fill in the appropriate TCP-layer header fields. To find the TCP header in a packet (assuming it has been enabledSectionsec:packethdrmgr) the off_tcp_ must be properly initialized, as illustrated in the constructor. The packet []access method returns a pointer to the TCP header, its sequence number and time stamp fields are filled in, and the []send method of the class Connector is called to send the packet downstream one hop. Note that the C++ :: scoping operator is used here to avoid calling []TcpSimpleAgent::send (which is also defined). The check for a pending timer uses the timer method []status which is defined in the base class TimerHandler. It is used here to set a retransmission timer if one is not already set (a TCP sender only sets one timer per window of packets on each connection).
Tom Henderson 2014-12-17