Http://www.isi.edu/nsnam/ns/tutorial/
1. The following table shows the approximate ing between ns2-and TCP/IP and OSI Layer-7 network structures (this table is very helpful)
TCP |
NS2. |
OSI |
Application Layer |
Application Layer |
Application Layer Presentation Layer Session Layer |
Transport Layer (TCP/UDP) Network Layer |
Agent) |
Transport Layer Network Layer |
Physical Layer |
Nodes and connections (Node & link) |
Data Link Layer Physical Layer |
|
|
|
2. Next we will demonstrate the entire process of implementing the self-compiled agent in NS2. it has basic guiding significance for the study of transport layer and network layer simulation.
Implementation reference: Marc greis 'tutorial http://www.isi.edu/nsnam/ns/tutorial/ VII. A new protocol for ns I use the NS-2.34 version, which has added agent/ping, here only verify the feasibility of Marc greis 'tutotial; the following is the entire implementation process: (the process is the same, but there are some differences between directories and implementation details. Note that, haha !) (I believe that reading and implementing the following tasks after reading the previous instances and running the test will not be a problem !) Generally, a protocol is implemented under NS2. it is mainly written. H and. CC files, but when the problem is complicated, you may need to write many files, but generally each. the H file corresponds to the corresponding. CC file.. H file, which is generally used to define the data packet format and class. CC file, you need to do the following: (1 ).. implementation of class methods defined in h, (2 ). the tclclass is compiled to provide interfaces for Tcl scripts. The code of this function remains unchanged and can be simply replaced each time. (3 ). the variables in Tcl scripts and the binding functions of class variables in C ++ can be entered directly! (4) The command function is the agent class and Tcl interface. The command of the Tcl script acts on this function directly! (5). The Recv function is the key to implementing the agent functions. This function is used to classify, forward, and process data packets in the network! Refer to the specific application to compile it! The following demonstrates the implementation process of agent/ping in Marc greis 'tutorial, and finally provides the test result! 1. Ping. h file:
/* File: header file for a new 'ping' agent class for NS * Author: Marc greis (greis@cs.uni-bonn.de ), May 1998 */ # Ifndef ns_ping_h # Define ns_ping_h # Include "agent. H" # Include "tclcl. H" # Include "packet. H" # Include "address. H" # Include "ip. H" Struct hdr_ping { Char ret; // the return value from the source is 0, and the return value from the target is 1; Double send_time; // The time file sent from the source for round-trip latency calculation; }; Class pingagent: public agent { Public: Pingagent (); Int command (INT argc, const char * const * argv ); Void Recv (packet *, Handler *); Protected: Int off_ping _; // It will be used to access a packet's ping Header }; # Endif |
2. Ping. CC file:
/* File: code for a new 'ping' agent class for NS * Author: Marc greis (greis@cs.uni-bonn.de ), May 1998 */ # Include "ping. H" // The following two functions are used to connect C ++ and OTCL. You can apply them each time and modify them accordingly! Static class pingheaderclass: Public packetheaderclass { Public: Pingheaderclass (): packetheaderclass ("packetheader/ping ", Sizeof (hdr_ping )){} } Class_pinghdr; Static class pingclass: Public tclclass { Public: Pingclass (): tclclass ("agent/ping "){} Tclobject * Create (INT, const char * const *){ Return (New pingagent ()); } } Class_ping; Pingagent: pingagent (): Agent (pt_ping) // constructor of pingagent { BIND ("packetsize _", & size _); BIND ("off_ping _", & off_ping _); } /× The function 'COMMAND () 'is called when a Tcl command for Class 'pingagent' is executed. In our case that wocould be '$ PA send' (Assuming 'pa' is an instance of the agent/ping class), because we want To send ping packets from the agent to another ping agent. You Basically have to parse the command in the 'COMMAND () 'function, and if No match is found, you have to pass the command with its arguments The 'COMMAND () 'function of the base class (in this case 'Agent: Command () '). ×/ // $ Pa send command as the command function input Int pingagent: Command (INT argc, const char * const * argv) { If (argc = 2 ){ If (strcmp (argv [1], "send") = 0 ){ // Create a new packet Packet * Pkt = allocpkt (); // Access the ping header for the new packet: Hdr_ping * HDR = (hdr_ping *) Pkt-> access (off_ping _); // Set the 'ret 'field to 0, so the grouping node knows // That it has to generate an ECHO packet HDR-> ret = 0; // Store the current time in the 'send _ time' Field HDR-> send_time = Scheduler: instance (). Clock (); // Send the packet Send (Pkt, 0 ); // Return tcl_ OK, so the calling function knows that // Command has been processed Return (tcl_ OK ); } } // If the command hasn't been processed by pingagent (): command, // Call the command () function for the base class Return (AGENT: Command (argc, argv )); } /× The function 'cv () 'defines the actions to be taken when Packet is already ed. If the 'ret 'field is 0, a packet with the same Value for the 'send _ time' field, but with the 'ret 'field set to 1 has To be returned. If 'ret 'is 1, a Tcl function (which has to be defined By the user in TCL) is called and processed the event .*/ Void pingagent: Recv (packet * Pkt, Handler *) { // Access the IP header for the specified ed packet: Hdr_ip * hdrip = (hdr_ip *) Pkt-> access (off_ip _); // Access the ping header for the specified ed packet: Hdr_ping * HDR = (hdr_ping *) Pkt-> access (off_ping _); // Is the 'ret 'field = 0 (I. e. the processing ing node is being pinged )? If (HDR-> ret = 0 ){ // Send an 'echo '. First save the old packet's send_time Double stime = HDR-> send_time; // Discard the packet Packet: Free (Pkt ); // Create a new packet Packet * pktret = allocpkt (); // Access the ping header for the new packet: Hdr_ping * hdrret = (hdr_ping *) pktret-> access (off_ping _); // Set the 'ret 'field to 1, so the receiver won't send another echo Hdrret-> ret = 1; // Set the send_time field to the correct value Hdrret-> send_time = stime; // Send the packet Send (pktret, 0 ); } Else { // A packet was encoded ed. Use TCL. eval to call the Tcl // Interpreter with the ping results. // Note: In the Tcl code, a procedure 'agent/ping Recv {from RTT }' // Has to be defined which allows the user to react to the Ping // Result. Char out [100]; // Prepare the output to the Tcl interpreter. Calculate the round // Trip time Sprintf (Out, "% s Recv % d % 3.1f", name (), Hdrip-> SRC _> address: instance (). nodeshift _ [1], (Schedck: instance (). Clock ()-HDR-> send_time) * 1000 ); TCL & TCL = TCL: instance (); TCL. eval (out ); // Discard the packet Packet: Free (Pkt ); } } |
Simple Protocol. These two files can be directly stored in ~ /Under the ns-2.xx/directory. Complex situations will be described in more detail in the following instances! 3. Necessary modifications in NS2. (1). "packet. H" file Enum packet_t {
Pt_tcp,
Pt_udp,
......
// Insert new packet types here
Pt_tfrc,
Pt_tfrc_ack,
Pt_ping, // packet protocol id for our Ping-agent
Pt_ntype // This must be the last one
}; Packet. h: Home/username/ns-allinone-2.34/ns-2.34/common/packet on my machine. h does not use enumeration for the definition of pt_ping, but is directly defined as the static const packet_t type :....... static const packet_t pt_tfrc = 42;
Static const packet_t pt_tfrc_ack = 43;
Static const packet_t pt_ping = 44; ...... modify class p_info {} structure: Class p_info {
Public:
P_info (){
Name _ [pt_tcp] = "TCP ";
Name _ [pt_udp] = "UDP ";
...........
Name _ [pt_tfrc] = "tcpfriend ";
Name _ [pt_tfrc_ack] = "tcpfriendctl ";
Name _ [pt_ping] = "ping"; // added
Name _ [pt_ntype] = "undefined ";
}
.....
} The implementation of this class on my machine is: Class p_info {
Public:
P_info (){
Initname (); // Therefore, I should modify it in initname !!
} ...... Static void initname ()
{
If (npkt _> = pt_ntype + 1)
Return;
Char ** namenew = new char * [pt_ntype + 1]; ...... name _ [pt_tfrc] = "tcpfriend ";
Name _ [pt_tfrc_ack] = "tcpfriendctl ";
Name _ [pt_ping] = "ping"; // it should be added! ................................ (2 ). tcl/lib/ns-default.tcl file (this is good to find Oh !) # Agent set seqno _ 0 now is gone
# Agent set class _ 0 now is gone agent/ping set packetsize _ 64 (3). Tcl/lib/ns-packet.tcl file {srmext off_srm_ext _}
{Ping off_ping _}}{
Set Cl packetheader/[lindex $ pair 0] On my server: # {UMP off_ump _}
# {TFRC off_tfrm _}
# {Ping off_ping _} // note that it has been commented out.
# {Rtprotols off_ls _}
# {MPLS off_mpls _}
# {GAF off_gaf _}
# {LDP off_ldp _}
#}{
# Create-packet-header [lindex $ pair 0] [lindex $ pair 1]
#} The foreach prot {} is implemented using the foreach prot {} structure {
# Common:
Common
Flags
IP # IP
# Routing protocols:
... # Application-layer protocols:
Message # A protocol to carry text messages
Ping # Ping
PBC # PBC ...... # Other:
Encap # common/encap. CC
Ipinip # IP Encapsulation
HDLC # High Level Data Link Control
}{
Add-packet-header $ prot
} The specific implementation mechanism is not very familiar yet, but it does not affect it. You only need to draw a gourd image! Haha! (4). makefile (this file must know where it is? Haha, if you don't know, it's a pity that you can pass the test, good luck !) Sessionhelper. O delaymodel. O srm-ssm.o/
Srm-topo.o/
Ping. O/
$ (Lib_dir) int. Vec. o $ (lib_dir) int. rvec. O/
$ (Lib_dir) dmalloc_support.o/on our machine, as shown in the following figure: diffusion/hash_table.o diffusion/routing_table.o diffusion/iflist. O/
TCP/TFRC. o tcp/tfrc-sink.o mobile/energy-model.o apps/ping. o tcp/tcp-rfc793edu.o/
Queue/Rio. O queue/semantic-rio.o TCP/tcp-sack-rh.o TCP/scoreboard-rh.o/from, you can see that my machine Ping. H and Ping. CC files are stored in the ns-2.34/apps/folder (the ping should be generated under this folder after the make command. o, but not found, and Ping. TCL code is executed as usual. Haha, let's think about it later !) (5). Run the make command or make clean make depend make (6). Run ping. TCL to test: Ping. TCL File
# Create a simulator object Set NS [New simulator] # Open a trace file Set tracefd [open out. tr w] $ NS trace-all $ tracefd Set NF [open out. Nam w] $ NS namtrace-all $ NF # Define a 'save' procedure Proc finish {}{ Global NS NF $ NS flush-trace Close $ NF Exec Nam out. Nam & Exit 0 } # Create three Nodes Set N0 [$ ns Node] Set N1 [$ ns Node] Set N2 [$ ns Node] # Connect the nodes with two links $ NS Duplex-link $ N0 $ N1 1 MB 10 ms droptail $ NS Duplex-link $ N1 $ N2 1 MB 10 ms droptail # Define a 'recv' function for the class 'agent/ping' Agent/ping instproc Recv {from RTT }{ $ Self instvar node _ Puts "Node [$ node _ id] pinned ed Ping answer from/ $ From with round-trip-time $ RTT Ms ." } # Create two Ping agents and attach them to the nodes N0 and N2 Set P0 [new agent/ping] $ NS attach-agent $ N0 $ P0 Set P1 [new agent/ping] $ NS attach-agent $ N2 $ p1 # Connect the two agents $ NS connect $ P0 $ p1 # Schedule events $ NS at 0.2 "$ P0 send" $ NS at 0.4 "$ P1 send" $ NS at 0.6 "$ P0 send" $ NS at 0.6 "$ P1 send" $ NS at 1.0 "finish" # Run the simulation $ NS run |
The command window output is as follows: