A multipath udp transmission demo on ns3

 The demo has only one single file and tested on ns-3.26.
mpudp.cc

#include "ns3/simulator.h"
#include "ns3/log.h"
#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/internet-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/node-list.h"
#include "ns3/socket.h"
#include<map>
#include<vector>
#include<cassert>
NS_LOG_COMPONENT_DEFINE ("MpUdp");
using namespace ns3;
using namespace std;
#define PACKET_SIZE 1000
bool IsExistRoute (Ptr<Node> node,Ipv4Address src, Ipv4Address dst)
{
  bool found = false;
  uint32_t interface=0;
  Ptr<Node> m_node=node;
  // Look up the source address
  Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
  assert (ipv4->GetRoutingProtocol () != 0); 
  Ipv4Header l3Header;
  Socket::SocketErrno errno_;
  Ptr<Ipv4Route> route;
  interface=ipv4->GetInterfaceForAddress(src);      //Pablo UC
  Ptr<NetDevice> oif=ipv4->GetNetDevice(interface); //Pablo UC
  l3Header.SetSource (src);
  l3Header.SetDestination (dst);
  route = ipv4->GetRoutingProtocol ()->RouteOutput (Ptr<Packet> (), l3Header, oif, errno_);
  if ((route != 0) && (src == route->GetSource ()))
  {
    NS_LOG_INFO ("IsThereRoute -> Route from srcAddr "<< src << " to dstAddr " << dst << " oit "<<oif<<", exist !");
    found = true;
  }else
    NS_LOG_INFO ("IsThereRoute -> No Route from srcAddr "<< src << " to dstAddr " << dst << " oit "<<oif<<", exist !");

  return found;
}
void GetNodeAddress(Ptr<Node>node,std::vector<Ipv4Address>&addresses)
{
	uint32_t interface=0;
	uint32_t totalInterface=0;
	Ptr<Ipv4> ipv4 =node->GetObject<Ipv4> ();
	totalInterface=ipv4->GetNInterfaces();
	NS_LOG_INFO("totalinterfaces "<<totalInterface);
	for(interface=0;interface<totalInterface;interface++)
	{
		Ipv4Address srcIp = ipv4->GetAddress (interface, 0).GetLocal ();
		if(srcIp==Ipv4Address::GetLoopback()) continue;
		addresses.push_back(srcIp);
		NS_LOG_INFO("srcIp "<<srcIp);
	}

}
struct AddressInfo
{
Ipv4Address srcIp;
Ipv4Address destIp;
uint16_t port;
};
class MpUdpReceiver:public ns3::Application
{
public:
	MpUdpReceiver(){}
	~MpUdpReceiver(){}
	void Bind(uint16_t port)
	{
		std::vector<Ipv4Address> srcAddresses;
		GetNodeAddress(GetNode(),srcAddresses);
		for(uint32_t i=0;i<srcAddresses.size();i++)
		{
			Ptr<Socket> socket=Socket::CreateSocket (GetNode (), UdpSocketFactory::GetTypeId ());
			auto local = InetSocketAddress{srcAddresses[i], port};
			auto ret=socket->Bind(local);
			NS_ASSERT (ret == 0);
			socket->SetRecvCallback (MakeCallback (&MpUdpReceiver::RecvPacket,this));
			m_sockets.insert(std::make_pair(srcAddresses[i],socket));
		}
		m_running = false;	
	}
private:
	void StartApplication()
	{
		m_running=true;
	}
	void StopApplication()
	{
		m_running=false;
	}
	void RecvPacket(Ptr<Socket>socket)
	{
	Address remoteAddr;
    auto packet = socket->RecvFrom (remoteAddr);
	auto srcIp = InetSocketAddress::ConvertFrom (remoteAddr).GetIpv4 ();
    auto srcPort = InetSocketAddress::ConvertFrom (remoteAddr).GetPort ();
	NS_LOG_INFO("recv from src "<<srcIp<<"port "<<srcPort);
	}
private:
	std::map<Ipv4Address,Ptr<Socket>>m_sockets;
	std::vector<AddressInfo>m_addrInfo;
	bool m_running{false};
};
class MpUdpSender:public ns3::Application
{
public:
	MpUdpSender(){}
	~MpUdpSender(){}
	void Init()
	{
		std::vector<Ipv4Address> srcAddresses;
		GetNodeAddress(GetNode(),srcAddresses);
		for(uint32_t i=0;i<srcAddresses.size();i++)
		{
			Ptr<Socket> socket=Socket::CreateSocket (GetNode (), UdpSocketFactory::GetTypeId ());
			auto local = InetSocketAddress{srcAddresses[i], 0};
			auto ret=socket->Bind(local);
			NS_ASSERT (ret == 0);
			socket->SetRecvCallback (MakeCallback (&MpUdpSender::RecvPacket,this));
			m_sockets.insert(std::make_pair(srcAddresses[i],socket));
		}
		Address addr;
	NS_LOG_INFO("print bind port info");
		for(auto it=m_sockets.begin();it!=m_sockets.end();it++)
		{
			Ptr<Socket> socket=it->second;
			socket->GetSockName(addr);
			InetSocketAddress iaddr = InetSocketAddress::ConvertFrom (addr);
			NS_LOG_INFO(iaddr.GetIpv4()<<"port "<<iaddr.GetPort());
			
		}
	}
	void AddPath(Ipv4Address destIp,uint16_t destPort)
	{
		for(auto it=m_sockets.begin();it!=m_sockets.end();it++)
		{
			Ipv4Address srcIp=it->first;
			if(IsExistRoute(GetNode(),srcIp,destIp))
			{
				AddressInfo info{srcIp,destIp,destPort};
				m_addrInfo.push_back(info);
			}
		}
	}
	void FakePacket()
	{
		if(m_gennerateTimer.IsExpired())
		{
			Ptr<Packet> packet=Create<Packet>(PACKET_SIZE);
			RoundRobinSchedule(packet);
			Time time=MilliSeconds(m_period);
			m_gennerateTimer=Simulator::Schedule(time,&MpUdpSender::FakePacket,this);
		}
	}
private:
	void StartApplication()
	{
		m_running=true;
		m_gennerateTimer=Simulator::ScheduleNow(&MpUdpSender::FakePacket,this);
	}
	void StopApplication()
	{
		m_running=false;
	}
	void RecvPacket(Ptr<Socket>socket)
	{
	//TODO
	}
	void RoundRobinSchedule(Ptr<Packet> packet)
	{
		uint32_t i=m_pathIndex;
		Ptr<Socket> socket;
		Ipv4Address destIp;
		uint16_t destPort;
		for(i;i<m_addrInfo.size();i++)
		{
			Ipv4Address srcIp=m_addrInfo[i].srcIp;
			auto it=m_sockets.find(srcIp);
			if(it!=m_sockets.end())
			{
			socket=it->second;
			destIp=m_addrInfo[i].destIp;
			destPort=m_addrInfo[i].port;
			break;
			}	
		}
		m_pathIndex=(i+1)%m_addrInfo.size();
		socket->SendTo(packet,0,InetSocketAddress{destIp,destPort});

	}
private:
	std::map<Ipv4Address,Ptr<Socket>>m_sockets;
	std::vector<AddressInfo>m_addrInfo;
	bool m_running{false};
	EventId m_gennerateTimer;
	uint32_t m_period{10};//in milliseconds
	uint8_t m_pathIndex{0};
	
};
static uint16_t servPort=5000;
static uint16_t queueSize=10;
static uint8_t links=3;
static int64_t startTime=0;
static int64_t stopTime=1000;
static int64_t endTime=2;//2s
int main(int argc, char *argv[])
{
	LogComponentEnable("MpUdp", LOG_LEVEL_ALL);
	NodeContainer n0n1;	
	n0n1.Create (2);
	
	InternetStackHelper stack;
	stack.Install (n0n1);	
	
	vector<Ipv4InterfaceContainer> ipv4Ints;
    for(int i=0; i <links; i++)
	{
	PointToPointHelper p2plink;
    p2plink.SetQueue ("ns3::DropTailQueue", "MaxPackets",UintegerValue(queueSize));
	p2plink.SetChannelAttribute("Delay", StringValue("10ms"));
	p2plink.SetDeviceAttribute ("DataRate", StringValue("5Mbps"));
	
	NetDeviceContainer netDevices;
    netDevices = p2plink.Install(n0n1);

    // Attribution of the IP addresses
    std::stringstream netAddr;
    netAddr << "10.1." << (i+1) << ".0";
    string str = netAddr.str();

    Ipv4AddressHelper ipv4addr;
    ipv4addr.SetBase(str.c_str(), "255.255.255.0");
    Ipv4InterfaceContainer interface = ipv4addr.Assign(netDevices);
    ipv4Ints.insert(ipv4Ints.end(), interface);
	}
	std::vector<Ipv4Address> destAddresses;
	GetNodeAddress(n0n1.Get(1),destAddresses);
	uint32_t i=0;
    Ptr<MpUdpSender> sendApp = CreateObject<MpUdpSender> ();
    Ptr<MpUdpReceiver> recvApp = CreateObject<MpUdpReceiver> ();
    n0n1.Get(0)->AddApplication (sendApp);
    n0n1.Get(1)->AddApplication (recvApp);
	recvApp->Bind(servPort);
	sendApp->Init();
	/*for(i=0;i<destAddresses.size();i++)
	{
		sendApp->AddPath(destAddresses[i],servPort);
		NS_LOG_INFO(destAddresses[i]);
	}
    sendApp->SetStartTime (MilliSeconds (startTime));
    sendApp->SetStopTime (MilliSeconds (stopTime));

    recvApp->SetStartTime (MilliSeconds (startTime));
    recvApp->SetStopTime (MilliSeconds (stopTime));	
	Simulator::Stop (Seconds (endTime));
    Simulator::Run ();
    Simulator::Destroy ();*/
	return 0;
}

 And the function void GetNodeAddress(Ptrnode,std::vector&addresses) is used to get the ip address from a node.

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值