-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtcp_congestion.c
342 lines (303 loc) · 13.5 KB
/
tcp_congestion.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
// TCP Reno Mechanism using Droptail & RED mechanism
#include <fstream>
#include <string>
#include <string>
#include <cassert>
#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/applications-module.h"
#include "ns3/animation-interface.h"
#include "ns3/internet-module.h"
#include "ns3/netanim-module.h"
#include "ns3/packet-sink.h"
#include "ns3/flow-monitor-helper.h"
#include "ns3/flow-monitor-module.h"
#include "ns3/ipv4-global-routing-helper.h"
#include "ns3/ipv4-flow-classifier.h"
#include "ns3/double.h"
#include "ns3/tcp-socket-base.h"
#include "ns3/tcp-l4-protocol.h"
using namespace ns3;
using namespace std;
NS_LOG_COMPONENT_DEFINE ("jcomp");
//MyApp Application
class MyApp : public Application
{
public:
MyApp ();
virtual ~MyApp();
void Setup (Ptr<Socket> socket, Address address, uint32_t
packetSize, uint32_t nPackets, DataRate dataRate);
private:
virtual void StartApplication (void);
virtual void StopApplication (void);
void ScheduleTx (void);
void SendPacket (void);
Ptr<Socket> m_socket;
Address m_peer;
uint32_t m_packetSize;
uint32_t m_nPackets;
DataRate m_dataRate;
EventId m_sendEvent;
bool m_running;
uint32_t m_packetsSent;
};
//Constructor and Destructor
MyApp::MyApp ()
: m_socket (0),
m_peer (),
m_packetSize (0),
m_nPackets (0),
m_dataRate (0),
m_sendEvent (),
m_running (false),
m_packetsSent (0)
{
}
MyApp::~MyApp()
{
m_socket = 0;
}
void MyApp::Setup (Ptr<Socket> socket, Address address, uint32_t packetSize, uint32_t nPackets, DataRate dataRate)
{
m_socket = socket;
m_peer = address;
m_packetSize = packetSize;
m_nPackets = nPackets;
m_dataRate = dataRate;
}
//Initializing member variables
void MyApp::StartApplication (void)
{
m_running = true;
m_packetsSent = 0;
m_socket->Bind ();
m_socket->Connect (m_peer);
SendPacket ();
}
//Stop creating simulation events
void MyApp::StopApplication (void)
{
m_running = false;
if (m_sendEvent.IsRunning ())
{
Simulator::Cancel (m_sendEvent);
}
if (m_socket)
{
m_socket->Close ();
}
}
//Recall that StartApplication called SendPacket to start the chain of events that describes the Application behavior
void MyApp::SendPacket (void)
{
Ptr<Packet> packet = Create<Packet> (m_packetSize);
m_socket->Send (packet);
if (++m_packetsSent < m_nPackets)
{
ScheduleTx ();
}
}
//Call ScheduleTx to schedule another transmit event (a SendPacket) until the Application decides it has sent enough.
void MyApp::ScheduleTx (void)
{
if (m_running)
{
Time tNext (Seconds (m_packetSize * 8 / static_cast<double> (m_dataRate.GetBitRate())));
m_sendEvent = Simulator::Schedule (tNext, &MyApp::SendPacket, this);
}
}
static void PrintTxQueue (Ptr <Queue> q0,Ptr <Queue> q1, Ptr <Queue> q2, Ptr <Queue> q3, Ptr <Queue> q4)
{
Simulator::Schedule (Seconds (0.001), &PrintTxQueue, q0, q1, q2, q3, q4);
std::cout << Simulator::Now ().GetSeconds () << "\t" << q0->GetNPackets()<< "\t" << q1->GetNPackets()<< "\t" << q2->GetNPackets()<< "\t" << q3->GetNPackets()<< "\t" << q4->GetNPackets()<<"\n";
}
int main (int argc, char *argv[])
{
uint32_t nFlows=5;
uint32_t packetSize=1400;
uint32_t nPackets=2000;
uint32_t j=1;
j = 0;
//For 5 buffer size
for(j=1;j<=5;j++)
{
uint bufSize=j*packetSize;
CommandLine cmd;
cmd.AddValue("nFlows","Number of TCP Flows",nFlows);
cmd.Parse(argc,argv);
Config::SetDefault("ns3::TcpL4Protocol::SocketType",StringValue("ns3::TcpReno"));
Config::SetDefault("ns3::DropTailQueue::Mode", StringValue("QUEUE_MODE_PACKETS"));
Config::SetDefault("ns3::DropTailQueue::MaxPackets",UintegerValue (j));
//Uncomment the below for RED mechanism & comment the above 2 lines
//Config::SetDefault ("ns3::RedQueue::Mode", StringValue("QUEUE_MODE_PACKETS"));
//Config::SetDefault ("ns3::RedQueue::MinTh", DoubleValue (1));
//Config::SetDefault ("ns3::RedQueue::MaxTh", DoubleValue (3));
//Config::SetDefault ("ns3::RedQueue::QueueLimit", UintegerValue (j));
Config::SetDefault("ns3::TcpSocket::SegmentSize", UintegerValue (1000));
Config::SetDefault("ns3::TcpSocket::InitialCwnd", UintegerValue (1));
Config::SetDefault("ns3::TcpSocketBase::MaxWindowSize", UintegerValue (20*1000));
NS_LOG_INFO ("Create Nodes.");
NodeContainer nodes;
nodes.Create (15);
NodeContainer n0n2 = NodeContainer (nodes.Get (0), nodes.Get (2)); //h1r1
NodeContainer n1n2 = NodeContainer (nodes.Get (1), nodes.Get (2)); //h2r1
NodeContainer n2n3 = NodeContainer (nodes.Get (2), nodes.Get (3)); //r1r2
NodeContainer n3n4 = NodeContainer (nodes.Get (3), nodes.Get (4)); //r2h3
NodeContainer n3n5 = NodeContainer (nodes.Get (3), nodes.Get (5)); //r2r3
NodeContainer n5n6 = NodeContainer (nodes.Get (5), nodes.Get (6)); //r3h4
NodeContainer n5n7 = NodeContainer (nodes.Get (5), nodes.Get (7)); //r3r4
NodeContainer n7n8 = NodeContainer (nodes.Get (7), nodes.Get (8)); //r4h5
NodeContainer n7n9 = NodeContainer (nodes.Get (7), nodes.Get (9)); //r4r5
NodeContainer n9n10 = NodeContainer (nodes.Get (9), nodes.Get (10)); //r5h6
NodeContainer n9n11 = NodeContainer (nodes.Get (9), nodes.Get (11)); //r5h7
NodeContainer n9n12 = NodeContainer (nodes.Get (9), nodes.Get (12)); //r5h8
NodeContainer n9n13 = NodeContainer (nodes.Get (9), nodes.Get (13)); //r5h9
NodeContainer n9n14 = NodeContainer (nodes.Get (9), nodes.Get (14)); //r5h10
InternetStackHelper internet;
internet.Install (nodes);
NS_LOG_INFO ("Create Channels.");
PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute ("DataRate", StringValue("10Mbps"));
pointToPoint.SetChannelAttribute ("Delay", StringValue ("100us"));
NetDeviceContainer d0d2 = pointToPoint.Install (n0n2);
NetDeviceContainer d1d2 = pointToPoint.Install (n1n2);
NetDeviceContainer d3d4 = pointToPoint.Install (n3n4);
NetDeviceContainer d5d6 = pointToPoint.Install (n5n6);
NetDeviceContainer d7d8 = pointToPoint.Install (n7n8);
NetDeviceContainer d9d10 = pointToPoint.Install (n9n10);
NetDeviceContainer d9d11 = pointToPoint.Install (n9n11);
NetDeviceContainer d9d12 = pointToPoint.Install (n9n12);
NetDeviceContainer d9d13 = pointToPoint.Install (n9n13);
NetDeviceContainer d9d14 = pointToPoint.Install (n9n14);
NetDeviceContainer d2d3 = pointToPoint.Install (n2n3);
NetDeviceContainer d3d5 = pointToPoint.Install (n3n5);
NetDeviceContainer d5d7 = pointToPoint.Install (n5n7);
NetDeviceContainer d7d9 = pointToPoint.Install (n7n9);
NS_LOG_INFO ("Assign IP Address5s.");
Ipv4AddressHelper ipv4;
ipv4.SetBase ("10.1.1.0", "255.255.255.0");
Ipv4InterfaceContainer i0i2 = ipv4.Assign (d0d2);
ipv4.SetBase ("10.1.2.0", "255.255.255.0");
Ipv4InterfaceContainer i1i2 = ipv4.Assign (d1d2);
ipv4.SetBase ("10.1.3.0", "255.255.255.0");
Ipv4InterfaceContainer i2i3 = ipv4.Assign (d2d3);
ipv4.SetBase ("10.1.4.0", "255.255.255.0");
Ipv4InterfaceContainer i3i4 = ipv4.Assign (d3d4);
ipv4.SetBase ("10.1.5.0", "255.255.255.0");
Ipv4InterfaceContainer i3i5 = ipv4.Assign (d3d5);
ipv4.SetBase ("10.1.6.0", "255.255.255.0");
Ipv4InterfaceContainer i5i6 = ipv4.Assign (d5d6);
ipv4.SetBase ("10.1.7.0", "255.255.255.0");
Ipv4InterfaceContainer i5i7 = ipv4.Assign (d5d7);
ipv4.SetBase ("10.1.8.0", "255.255.255.0");
Ipv4InterfaceContainer i7i8 = ipv4.Assign (d7d8);
ipv4.SetBase ("10.1.9.0", "255.255.255.0");
Ipv4InterfaceContainer i7i9 = ipv4.Assign (d7d9);
ipv4.SetBase ("10.1.10.0", "255.255.255.0");
Ipv4InterfaceContainer i9i10 = ipv4.Assign (d9d10);
ipv4.SetBase ("10.1.11.0", "255.255.255.0");
Ipv4InterfaceContainer i9i11 = ipv4.Assign (d9d11);
ipv4.SetBase ("10.1.12.0", "255.255.255.0");
Ipv4InterfaceContainer i9i12 = ipv4.Assign (d9d12);
ipv4.SetBase ("10.1.13.0", "255.255.255.0");
Ipv4InterfaceContainer i9i13 = ipv4.Assign (d9d13);
ipv4.SetBase ("10.1.14.0", "255.255.255.0");
Ipv4InterfaceContainer i9i14 = ipv4.Assign (d9d14);
NS_LOG_INFO ("Enable static global routing.");
Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
//Set up TCP server connection
uint16_t port = 8000;
ApplicationContainer sinkApp;
Address sinkLocalAddress(InetSocketAddress (Ipv4Address::GetAny (), port));
PacketSinkHelper sinkHelper ("ns3::TcpSocketFactory", sinkLocalAddress);
sinkApp.Add(sinkHelper.Install(n9n10.Get(1)));
sinkApp.Add(sinkHelper.Install(n9n11.Get(1)));
sinkApp.Add(sinkHelper.Install(n9n12.Get(1)));
sinkApp.Add(sinkHelper.Install(n9n13.Get(1)));
sinkApp.Add(sinkHelper.Install(n9n14.Get(1)));
sinkApp.Start (Seconds (0.5));
sinkApp.Stop (Seconds (3.5));
//Create the socket and connect the Trace source
Ptr<Socket> ns3TcpSocket1 = Socket::CreateSocket (nodes.Get (0), TcpSocketFactory::GetTypeId ());
Ptr<Socket> ns3TcpSocket2 = Socket::CreateSocket (nodes.Get (1), TcpSocketFactory::GetTypeId ());
Ptr<Socket> ns3TcpSocket3 = Socket::CreateSocket (nodes.Get (4), TcpSocketFactory::GetTypeId ());
Ptr<Socket> ns3TcpSocket4 = Socket::CreateSocket (nodes.Get (6), TcpSocketFactory::GetTypeId ());
Ptr<Socket> ns3TcpSocket5 = Socket::CreateSocket (nodes.Get (8), TcpSocketFactory::GetTypeId ());
//Create object of MyApp
Ptr<MyApp> clientApp1 = CreateObject<MyApp>();
Ptr<MyApp> clientApp2 = CreateObject<MyApp>();
Ptr<MyApp> clientApp3 = CreateObject<MyApp>();
Ptr<MyApp> clientApp4 = CreateObject<MyApp>();
Ptr<MyApp> clientApp5 = CreateObject<MyApp>();
//Make connections
Ipv4Address clientAddress1 = i0i2.GetAddress (0);
AddressValue localAddress1 (InetSocketAddress (clientAddress1, port));
Ipv4Address serverAddress1 = i9i10.GetAddress (1);
Address remoteAddress1 (InetSocketAddress (serverAddress1, port));
Ipv4Address clientAddress2 = i1i2.GetAddress (0);
AddressValue localAddress2 (InetSocketAddress (clientAddress2, port));
Ipv4Address serverAddress2 = i9i11.GetAddress (1);
Address remoteAddress2 (InetSocketAddress (serverAddress2, port));
Ipv4Address clientAddress3 = i3i4.GetAddress (1);
AddressValue localAddress3 (InetSocketAddress (clientAddress3, port));
Ipv4Address serverAddress3 = i9i12.GetAddress (1);
Address remoteAddress3 (InetSocketAddress (serverAddress3, port));
Ipv4Address clientAddress4 = i5i6.GetAddress (1);
AddressValue localAddress4 (InetSocketAddress (clientAddress4, port));
Ipv4Address serverAddress4 = i9i13.GetAddress (1);
Address remoteAddress4 (InetSocketAddress (serverAddress4, port));
Ipv4Address clientAddress5 = i7i8.GetAddress (1);
AddressValue localAddress5 (InetSocketAddress (clientAddress5, port));
Ipv4Address serverAddress5 = i9i14.GetAddress (1);
Address remoteAddress5 (InetSocketAddress (serverAddress5, port));
//Bind socket with application and connect to server
clientApp1->Setup(ns3TcpSocket1, remoteAddress1, packetSize,nPackets, DataRate("2Mbps"));
clientApp2->Setup(ns3TcpSocket2, remoteAddress2, packetSize,nPackets, DataRate("2Mbps"));
clientApp3->Setup(ns3TcpSocket3, remoteAddress3, packetSize,nPackets, DataRate("2Mbps"));
clientApp4->Setup(ns3TcpSocket4, remoteAddress4, packetSize,nPackets, DataRate("2Mbps"));
clientApp5->Setup(ns3TcpSocket5, remoteAddress5, packetSize,nPackets, DataRate("2Mbps"));
//Install application to Client
nodes.Get (0)->AddApplication(clientApp1);
nodes.Get (1)->AddApplication(clientApp2);
nodes.Get (4)->AddApplication(clientApp3);
nodes.Get (6)->AddApplication(clientApp4);
nodes.Get (8)->AddApplication(clientApp5);
//Set start and stop time
clientApp1->SetStartTime(Seconds(1.0));
clientApp1->SetStopTime(Seconds(3.0));
clientApp2->SetStartTime(Seconds(1.0));
clientApp2->SetStopTime(Seconds(3.0));
clientApp3->SetStartTime(Seconds(1.0));
clientApp3->SetStopTime(Seconds(3.0));
clientApp4->SetStartTime(Seconds(1.0));
clientApp4->SetStopTime(Seconds(3.0));
clientApp5->SetStartTime(Seconds(1.0));
clientApp5->SetStopTime(Seconds(3.0));
//Trace file
AsciiTraceHelper ascii;
pointToPoint.EnableAsciiAll (ascii.CreateFileStream ("jcomptrace.tr"));
//Calculate Throughput using Flowmonitor
FlowMonitorHelper flowmon;
Ptr<FlowMonitor> monitor = flowmon.InstallAll();
NS_LOG_INFO ("Run Simulation.");
Simulator::Stop (Seconds(3));
Simulator::Run ();
monitor->CheckForLostPackets ();
Ptr<Ipv4FlowClassifier> classifier = DynamicCast<Ipv4FlowClassifier> (flowmon.GetClassifier());
std::map<FlowId, FlowMonitor::FlowStats> stats = monitor->GetFlowStats ();
std::cout<<"\n" << j <<"\t";
std::cout <<" Buffer size " <<bufSize <<"\n" ;
for (std::map<FlowId, FlowMonitor::FlowStats>::const_iterator i = stats.begin(); i != stats.end(); ++i)
{
Ipv4FlowClassifier::FiveTuple t = classifier->FindFlow (i->first);
std::cout << "Flow " << i->first << " (" << t.sourceAddress << " -> " << t.destinationAddress << ") - "<<"\n";
std::cout << " Tx Bytes: " << i->second.txBytes << "\n";
std::cout << " Rx Bytes: " << i->second.rxBytes << "\n";
std::cout << " PacketLoss: " <<i->second.lostPackets<<"\n";
std::cout << " Throughput: " << i->second.rxBytes * 8.0 / (i->second.timeLastRxPacket.GetSeconds() - i->second.timeFirstTxPacket.GetSeconds())/1024/1024 << " Mbps\n";
}
Simulator::Destroy ();
}
}