/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/csma-module.h"
#include "ns3/internet-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/applications-module.h"
#include "ns3/ipv4-global-routing-helper.h"
// Default Network Topology
//
// 10.1.1.0
// n0 -------------- n1 n2 n3 n4
// point-to-point | | | |
// ================
// LAN 10.1.2.0
/* n0和n1是 点对点通信,n1/n2/n3/n4是csma网络(有线网络)。
意味着:n1需要两个网络设备,一个PointToPoint(点对点)的网络设备,一个是csma的网络设备
*/
using namespace ns3;
NS_LOG_COMPONENT_DEFINE ("SecondScriptExample");
int
main (int argc, char *argv[])
{
// 定义bool变量用于决定是否开启日志组建(默认开启->true)
bool verbose = true;
// 变量nCsma,用于定义csma网络中的有多少个节点->3个节点
uint32_t nCsma = 3;
CommandLine cmd;
cmd.AddValue ("nCsma", "Number of \"extra\" CSMA nodes/devices", nCsma);
cmd.AddValue ("verbose", "Tell echo applications to log if true", verbose);
cmd.Parse (argc,argv);
if (verbose)
{
LogComponentEnable ("UdpEchoClientApplication", LOG_LEVEL_INFO);
LogComponentEnable ("UdpEchoServerApplication", LOG_LEVEL_INFO);
}
nCsma = nCsma == 0 ? 1 : nCsma;
/**************网络拓扑部分************/
// 创建PointToPoint节点->(n0&n1)
NodeContainer p2pNodes;
p2pNodes.Create (2);
// 创建csma网络节点(3个csma节点),并把n1加到csma网络节点的容器内->(n1&n2&n3&n4)
NodeContainer csmaNodes;
csmaNodes.Add (p2pNodes.Get (1));//把PointToPoint节点容器内第二个节点(n1,列表下标为1)加入到csma节点容器内
csmaNodes.Create (nCsma);
// 设置p2p传输速率和信道延迟,同first.cc
PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));//数据速率5Mbps
pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));//信道延时2ms
// 安装p2p网络设备到p2p网络节点,同first.cc
NetDeviceContainer p2pDevices;
p2pDevices = pointToPoint.Install (p2pNodes);
// 设置csma的传输速率和信道延时
CsmaHelper csma;
csma.SetChannelAttribute ("DataRate", StringValue ("100Mbps"));//csma中传输数据速率由信道决定->csma不允许同一信道上有多个不同传输速率的设备
csma.SetChannelAttribute ("Delay", TimeValue (NanoSeconds (6560)));
// 安装网络设备到csma节点->共nCsma+1个(4个)
NetDeviceContainer csmaDevices;
csmaDevices = csma.Install (csmaNodes);//csmaNodes里有四个节点(n1~n4)
// 安装网络协议栈
InternetStackHelper stack;
stack.Install (p2pNodes.Get (0));//在p2p中的n0节点上安装
stack.Install (csmaNodes);//p2p中的第二个节点包含在csmaNodes中,在n1~n4上安装
// 分配地址
Ipv4AddressHelper address;
// 分配p2p网段的地址
address.SetBase ("10.1.1.0", "255.255.255.0");//设置p2p网段的地址
// n0:10.1.1.0;n1:10.1.1.1
Ipv4InterfaceContainer p2pInterfaces;
p2pInterfaces = address.Assign (p2pDevices);//把网段地址应用在p2p的网络设备上
// 分配csma网段的地址
address.SetBase ("10.1.2.0", "255.255.255.0");
//n1:10.1.2.1;n2:10.1.2.2;n3:10.1.2.3;n4:10.1.2.4;
Ipv4InterfaceContainer csmaInterfaces;
csmaInterfaces = address.Assign (csmaDevices);
/**************网络拓扑部分结束************/
/*************应用程序部分************/
// 设置udp服务端网络端口号为9
UdpEchoServerHelper echoServer (9);
// 将服务端服务安装在csma网段的最后一个nCsma节点上(n4)
ApplicationContainer serverApps = echoServer.Install (csmaNodes.Get (nCsma));
serverApps.Start (Seconds (1.0));//1s开始
serverApps.Stop (Seconds (10.0));//10s结束
// 设置客户端对应远程服务器的IP地址和端口号
UdpEchoClientHelper echoClient (csmaInterfaces.GetAddress (nCsma), 9);
echoClient.SetAttribute ("MaxPackets", UintegerValue (1));//最大数据分组个数1个
echoClient.SetAttribute ("Interval", TimeValue (Seconds (1.0)));//2个数据分组之间要等待1s
echoClient.SetAttribute ("PacketSize", UintegerValue (1024));//数据分组应该承载多少数据1024byte
// 将客户端服务安装在p2p网段的第一个节点上(n0)
ApplicationContainer clientApps = echoClient.Install (p2pNodes.Get (0));
clientApps.Start (Seconds (2.0));//2s开始
clientApps.Stop (Seconds (10.0));//10s结束
/*************应用程序部分结束************/
/*************调用全局路由Helper帮助建立网络路由************/
//根据节点产生的链路通告为每个节点建立路由表
Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
/*************开启pcap追踪************/
pointToPoint.EnablePcapAll ("second");
csma.EnablePcap ("second", csmaDevices.Get (1), true);
/*************进行模拟并回收资源************/
Simulator::Run ();
Simulator::Destroy ();
return 0;
}
在…/ns-3.30.1 的文件夹下运行
sudo ./waf --run scratch/second
返回上一层目录(ns-3.30.1文件夹下面)会发现3个追踪文件。
second-0-0.pcap追踪的是点到点网络设备上节点0、设备0的跟踪文件(节点n0)。
second-1-0.pcap追踪的是节点n1,节点1既有点到点设备又有csma设备,second-2-0.pcap是csma网络上的第一个“额外”节点(n2)。
运行second-0-0.pcap文件,查看节点0。
tcpdump -nn -tt -r second-0-0.pcap
链路是PPP(点到点)类型的,数据分组离开节点0,途径IP地址为10.1.1.1的关联设备,奔向IP地址为10.1.2.4的最右边csma节点。
运行second-1-0.pcap文件,查看节点1。
tcpdump -nn -tt -r second-1-0.pcap
这里链路类型也是PPP,来自IP地址10.1.1.1的数据分组(在2.000 000s被发送到IP地址10.1.2.4)出现在该接口上。这时(2.003686s),数据分组被转发到csma接口,然后发送到最终的目的地(IP:10.1.2.4)。
(注意:second-0-0.pcap和second-1-0.pcap 的不同之处在于时间点,节点0显示了整个数据分组转发的过程:数据分组从n0出发到n1,然后在n1转换到csma的接口,再从n1发送到n4,最后n4z再把数据返回给n0。这整个的过程用的时间是2.000 000s~2.007 607s。
而second-1-0.pcap中时间是从2.003 686s开始的,这个过程描述的是:数据分组到n1时,从p2p接口转发到csma接口,然后把数据发送到n4(IP:10.1.2.4),最后n4把数据返回给n1。这整个过程用的时间是:2.003 686s~2.003 921s)
运行second-2-0.pcap。
tcpdump -nn -tt -r second-2-0.pcap
节点2是csma网络混杂嗅探节点。
现在链路类型是“以太网”,总线网络需要ARP地址解析协议。节点1知道它需要发送数据分组到IP地址为10.1.2.4,但它不知道相应节点的MAC地址。于是在csma网络(FF:FF:FF:FF:FF:FF)上广播寻找IP地址为10.1.2.4的设备。在这种情况下,最右边的节点回答说其MAC地址是00:00:00:00:00:06。(节点2不直接参与这种交流,但嗅探网络并且报告所有流量)
节点1、设备1发送回显数据分组为IP地址为10.1.2.4的UDP回显服务器。服务器接收到回显请求后试图将数据分组发回给源头,服务器指导其地址在另一个网络(IP地址为10.1.2.1)上,这是因为初始化了全局路由。但是回显服务器节点不知道第一个csma节点的MAC地址,所以如同第一个csma节点所做的,它发送了ARP。
查看可视化界面:
sudo ./waf --run scratch/second --vis