A Discrete-Event Network Simulator
Home
Tutorials ▼
English
Portuguese
Docs ▼
Wiki
Manual
Models
Develop ▼
API
Bugs
API
Main Page
Related Pages
Modules
Namespaces
Classes
Files
File List
File Members
All
Classes
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Properties
Friends
Macros
Groups
Pages
tcp-large-transfer.cc
Go to the documentation of this file.
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
* This program is free software; you can redistribute it and/or modify
4
* it under the terms of the GNU General Public License version 2 as
5
* published by the Free Software Foundation;
6
*
7
* This program is distributed in the hope that it will be useful,
8
* but WITHOUT ANY WARRANTY; without even the implied warranty of
9
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
* GNU General Public License for more details.
11
*
12
* You should have received a copy of the GNU General Public License
13
* along with this program; if not, write to the Free Software
14
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15
*
16
*/
17
18
//
19
// Network topology
20
//
21
// 10Mb/s, 10ms 10Mb/s, 10ms
22
// n0-----------------n1-----------------n2
23
//
24
//
25
// - Tracing of queues and packet receptions to file
26
// "tcp-large-transfer.tr"
27
// - pcap traces also generated in the following files
28
// "tcp-large-transfer-$n-$i.pcap" where n and i represent node and interface
29
// numbers respectively
30
// Usage (e.g.): ./waf --run tcp-large-transfer
31
32
#include <iostream>
33
#include <fstream>
34
#include <string>
35
36
#include "ns3/core-module.h"
37
#include "ns3/applications-module.h"
38
#include "ns3/network-module.h"
39
#include "ns3/internet-module.h"
40
#include "ns3/point-to-point-module.h"
41
#include "ns3/ipv4-global-routing-helper.h"
42
43
using namespace
ns3;
44
45
NS_LOG_COMPONENT_DEFINE
(
"TcpLargeTransfer"
);
46
47
48
// The number of bytes to send in this simulation.
49
static
const
uint32_t
totalTxBytes
= 2000000;
50
static
uint32_t
currentTxBytes
= 0;
51
// Perform series of 1040 byte writes (this is a multiple of 26 since
52
// we want to detect data splicing in the output stream)
53
static
const
uint32_t
writeSize
= 1040;
54
uint8_t
data
[
writeSize
];
55
56
// These are for starting the writing process, and handling the sending
57
// socket's notification upcalls (events). These two together more or less
58
// implement a sending "Application", although not a proper ns3::Application
59
// subclass.
60
61
void
StartFlow
(
Ptr<Socket>
,
Ipv4Address
, uint16_t);
62
void
WriteUntilBufferFull
(
Ptr<Socket>
, uint32_t);
63
64
static
void
65
CwndTracer
(uint32_t oldval, uint32_t newval)
66
{
67
NS_LOG_INFO
(
"Moving cwnd from "
<< oldval <<
" to "
<< newval);
68
}
69
70
int
main
(
int
argc,
char
*argv[])
71
{
72
// Users may find it convenient to turn on explicit debugging
73
// for selected modules; the below lines suggest how to do this
74
// LogComponentEnable("TcpL4Protocol", LOG_LEVEL_ALL);
75
// LogComponentEnable("TcpSocketImpl", LOG_LEVEL_ALL);
76
// LogComponentEnable("PacketSink", LOG_LEVEL_ALL);
77
// LogComponentEnable("TcpLargeTransfer", LOG_LEVEL_ALL);
78
79
CommandLine
cmd;
80
cmd.
Parse
(argc, argv);
81
82
// initialize the tx buffer.
83
for
(uint32_t i = 0; i <
writeSize
; ++i)
84
{
85
char
m = toascii (97 + i % 26);
86
data
[i] = m;
87
}
88
89
// Here, we will explicitly create three nodes. The first container contains
90
// nodes 0 and 1 from the diagram above, and the second one contains nodes
91
// 1 and 2. This reflects the channel connectivity, and will be used to
92
// install the network interfaces and connect them with a channel.
93
NodeContainer
n0n1;
94
n0n1.
Create
(2);
95
96
NodeContainer
n1n2
;
97
n1n2.
Add
(n0n1.
Get
(1));
98
n1n2.
Create
(1);
99
100
// We create the channels first without any IP addressing information
101
// First make and configure the helper, so that it will put the appropriate
102
// attributes on the network interfaces and channels we are about to install.
103
PointToPointHelper
p2p;
104
p2p.
SetDeviceAttribute
(
"DataRate"
,
DataRateValue
(
DataRate
(10000000)));
105
p2p.
SetChannelAttribute
(
"Delay"
,
TimeValue
(MilliSeconds (10)));
106
107
// And then install devices and channels connecting our topology.
108
NetDeviceContainer
dev0 = p2p.
Install
(n0n1);
109
NetDeviceContainer
dev1 = p2p.
Install
(n1n2);
110
111
// Now add ip/tcp stack to all nodes.
112
InternetStackHelper
internet;
113
internet.
InstallAll
();
114
115
// Later, we add IP addresses.
116
Ipv4AddressHelper
ipv4;
117
ipv4.
SetBase
(
"10.1.3.0"
,
"255.255.255.0"
);
118
ipv4.
Assign
(dev0);
119
ipv4.
SetBase
(
"10.1.2.0"
,
"255.255.255.0"
);
120
Ipv4InterfaceContainer
ipInterfs = ipv4.
Assign
(dev1);
121
122
// and setup ip routing tables to get total ip-level connectivity.
123
Ipv4GlobalRoutingHelper::PopulateRoutingTables
();
124
126
// Simulation 1
127
//
128
// Send 2000000 bytes over a connection to server port 50000 at time 0
129
// Should observe SYN exchange, a lot of data segments and ACKS, and FIN
130
// exchange. FIN exchange isn't quite compliant with TCP spec (see release
131
// notes for more info)
132
//
134
135
uint16_t servPort = 50000;
136
137
// Create a packet sink to receive these packets on n2...
138
PacketSinkHelper
sink (
"ns3::TcpSocketFactory"
,
139
InetSocketAddress
(
Ipv4Address::GetAny
(), servPort));
140
141
ApplicationContainer
apps = sink.
Install
(n1n2.
Get
(1));
142
apps.
Start
(Seconds (0.0));
143
apps.
Stop
(Seconds (3.0));
144
145
// Create a source to send packets from n0. Instead of a full Application
146
// and the helper APIs you might see in other example files, this example
147
// will use sockets directly and register some socket callbacks as a sending
148
// "Application".
149
150
// Create and bind the socket...
151
Ptr<Socket>
localSocket =
152
Socket::CreateSocket
(n0n1.
Get
(0),
TcpSocketFactory::GetTypeId
());
153
localSocket->
Bind
();
154
155
// Trace changes to the congestion window
156
Config::ConnectWithoutContext
(
"/NodeList/0/$ns3::TcpL4Protocol/SocketList/0/CongestionWindow"
,
MakeCallback
(&
CwndTracer
));
157
158
// ...and schedule the sending "Application"; This is similar to what an
159
// ns3::Application subclass would do internally.
160
Simulator::ScheduleNow
(&
StartFlow
, localSocket,
161
ipInterfs.
GetAddress
(1), servPort);
162
163
// One can toggle the comment for the following line on or off to see the
164
// effects of finite send buffer modelling. One can also change the size of
165
// said buffer.
166
167
//localSocket->SetAttribute("SndBufSize", UintegerValue(4096));
168
169
//Ask for ASCII and pcap traces of network traffic
170
AsciiTraceHelper
ascii;
171
p2p.
EnableAsciiAll
(ascii.CreateFileStream (
"tcp-large-transfer.tr"
));
172
p2p.
EnablePcapAll
(
"tcp-large-transfer"
);
173
174
// Finally, set up the simulator to run. The 1000 second hard limit is a
175
// failsafe in case some change above causes the simulation to never end
176
Simulator::Stop
(Seconds (1000));
177
Simulator::Run
();
178
Simulator::Destroy
();
179
}
180
181
182
//-----------------------------------------------------------------------------
183
//-----------------------------------------------------------------------------
184
//-----------------------------------------------------------------------------
185
//begin implementation of sending "Application"
186
void
StartFlow
(
Ptr<Socket>
localSocket,
187
Ipv4Address
servAddress,
188
uint16_t servPort)
189
{
190
NS_LOG_LOGIC
(
"Starting flow at time "
<<
Simulator::Now
().GetSeconds ());
191
localSocket->
Connect
(
InetSocketAddress
(servAddress, servPort));
//connect
192
193
// tell the tcp implementation to call WriteUntilBufferFull again
194
// if we blocked and new tx buffer space becomes available
195
localSocket->
SetSendCallback
(
MakeCallback
(&
WriteUntilBufferFull
));
196
WriteUntilBufferFull
(localSocket, localSocket->
GetTxAvailable
());
197
}
198
199
void
WriteUntilBufferFull
(
Ptr<Socket>
localSocket, uint32_t txSpace)
200
{
201
while
(currentTxBytes < totalTxBytes && localSocket->GetTxAvailable () > 0)
202
{
203
uint32_t left =
totalTxBytes
-
currentTxBytes
;
204
uint32_t dataOffset = currentTxBytes %
writeSize
;
205
uint32_t toWrite =
writeSize
- dataOffset;
206
toWrite = std::min (toWrite, left);
207
toWrite = std::min (toWrite, localSocket->
GetTxAvailable
());
208
int
amountSent = localSocket->
Send
(&
data
[dataOffset], toWrite, 0);
209
if
(amountSent < 0)
210
{
211
// we will be called again when new tx space becomes available.
212
return
;
213
}
214
currentTxBytes += amountSent;
215
}
216
localSocket->
Close
();
217
}
examples
tcp
tcp-large-transfer.cc
Generated on Fri Aug 30 2013 01:42:44 for ns-3 by
1.8.1.2