A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
udp-trace-client.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2007,2008, 2009 INRIA, UDcast
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Mohamed Amine Ismail <amine.ismail@sophia.inria.fr>
19  * <amine.ismail@udcast.com>
20  */
21 #include "ns3/log.h"
22 #include "ns3/ipv4-address.h"
23 #include "ns3/nstime.h"
24 #include "ns3/inet-socket-address.h"
25 #include "ns3/inet6-socket-address.h"
26 #include "ns3/socket.h"
27 #include "ns3/simulator.h"
28 #include "ns3/socket-factory.h"
29 #include "ns3/packet.h"
30 #include "ns3/uinteger.h"
31 #include "ns3/string.h"
32 #include "seq-ts-header.h"
33 #include "udp-trace-client.h"
34 #include <stdlib.h>
35 #include <stdio.h>
36 #include <fstream>
37 
38 namespace ns3 {
39 
40 NS_LOG_COMPONENT_DEFINE ("UdpTraceClient");
41 NS_OBJECT_ENSURE_REGISTERED (UdpTraceClient);
42 
43 struct UdpTraceClient::TraceEntry UdpTraceClient::g_defaultEntries[] = {
44  { 0, 534, 'I'},
45  { 40, 1542, 'P'},
46  { 120, 134, 'B'},
47  { 80, 390, 'B'},
48  { 240, 765, 'P'},
49  { 160, 407, 'B'},
50  { 200, 504, 'B'},
51  { 360, 903, 'P'},
52  { 280, 421, 'B'},
53  { 320, 587, 'B'}
54 };
55 
56 TypeId
58 {
59  static TypeId tid = TypeId ("ns3::UdpTraceClient")
61  .AddConstructor<UdpTraceClient> ()
62  .AddAttribute ("RemoteAddress",
63  "The destination Address of the outbound packets",
64  AddressValue (),
65  MakeAddressAccessor (&UdpTraceClient::m_peerAddress),
66  MakeAddressChecker ())
67  .AddAttribute ("RemotePort",
68  "The destination port of the outbound packets",
69  UintegerValue (100),
70  MakeUintegerAccessor (&UdpTraceClient::m_peerPort),
71  MakeUintegerChecker<uint16_t> ())
72  .AddAttribute ("MaxPacketSize",
73  "The maximum size of a packet.",
74  UintegerValue (1024),
75  MakeUintegerAccessor (&UdpTraceClient::m_maxPacketSize),
76  MakeUintegerChecker<uint32_t> ())
77  .AddAttribute ("TraceFilename",
78  "Name of file to load a trace from. By default, uses a hardcoded trace.",
79  StringValue (""),
80  MakeStringAccessor (&UdpTraceClient::SetTraceFile),
81  MakeStringChecker ())
82 
83  ;
84  return tid;
85 }
86 
88 {
89  NS_LOG_FUNCTION (this);
90  m_sent = 0;
91  m_socket = 0;
92  m_sendEvent = EventId ();
93  m_maxPacketSize = 1400;
94 }
95 
97  char *traceFile)
98 {
99  NS_LOG_FUNCTION (this);
100  m_sent = 0;
101  m_socket = 0;
102  m_sendEvent = EventId ();
103  m_peerAddress = ip;
104  m_peerPort = port;
105  m_currentEntry = 0;
106  m_maxPacketSize = 1400;
107  if (traceFile != NULL)
108  {
109  SetTraceFile (traceFile);
110  }
111 }
112 
114 {
115  NS_LOG_FUNCTION (this);
116  m_entries.clear ();
117 }
118 
119 void
121 {
122  m_entries.clear ();
123  m_peerAddress = ip;
124  m_peerPort = port;
125 }
126 
127 void
129 {
130  m_entries.clear ();
131  m_peerAddress = Address (ip);
132  m_peerPort = port;
133 }
134 
135 void
137 {
138  m_entries.clear ();
139  m_peerAddress = Address (ip);
140  m_peerPort = port;
141 }
142 
143 void
144 UdpTraceClient::SetTraceFile (std::string traceFile)
145 {
146  if (traceFile == "")
147  {
148  LoadDefaultTrace ();
149  }
150  else
151  {
152  LoadTrace (traceFile);
153  }
154 }
155 
156 void
157 UdpTraceClient::SetMaxPacketSize (uint16_t maxPacketSize)
158 {
159  m_maxPacketSize = maxPacketSize;
160 }
161 
162 
164 {
165  return m_maxPacketSize;
166 }
167 
168 
169 void
171 {
174 }
175 
176 void
177 UdpTraceClient::LoadTrace (std::string filename)
178 {
179  NS_LOG_FUNCTION (this << filename);
180  uint32_t time, index, prevTime = 0;
181  uint16_t size;
182  char frameType;
183  TraceEntry entry;
184  std::ifstream ifTraceFile;
185  ifTraceFile.open (filename.c_str (), std::ifstream::in);
186  m_entries.clear ();
187  if (!ifTraceFile.good ())
188  {
189  LoadDefaultTrace ();
190  }
191  while (ifTraceFile.good ())
192  {
193  ifTraceFile >> index >> frameType >> time >> size;
194  if (frameType == 'B')
195  {
196  entry.timeToSend = 0;
197  }
198  else
199  {
200  entry.timeToSend = time - prevTime;
201  prevTime = time;
202  }
203  entry.packetSize = size;
204  entry.frameType = frameType;
205  m_entries.push_back (entry);
206  }
207  ifTraceFile.close ();
208  m_currentEntry = 0;
209 }
210 
211 void
213 {
214  NS_LOG_FUNCTION (this);
215  uint32_t prevTime = 0;
216  for (uint32_t i = 0; i < (sizeof (g_defaultEntries) / sizeof (struct TraceEntry)); i++)
217  {
218  struct TraceEntry entry = g_defaultEntries[i];
219  if (entry.frameType == 'B')
220  {
221  entry.timeToSend = 0;
222  }
223  else
224  {
225  uint32_t tmp = entry.timeToSend;
226  entry.timeToSend -= prevTime;
227  prevTime = tmp;
228  }
229  m_entries.push_back (entry);
230  }
231  m_currentEntry = 0;
232 }
233 
234 void
236 {
237  NS_LOG_FUNCTION (this);
238 
239  if (m_socket == 0)
240  {
241  TypeId tid = TypeId::LookupByName ("ns3::UdpSocketFactory");
244  {
245  m_socket->Bind ();
247  }
248  else if (Ipv6Address::IsMatchingType(m_peerAddress) == true)
249  {
250  m_socket->Bind6 ();
252  }
253  }
256 }
257 
258 void
260 {
261  NS_LOG_FUNCTION (this);
263 }
264 
265 void
267 {
268  NS_LOG_FUNCTION (this << size);
269  Ptr<Packet> p;
270  uint32_t packetSize;
271  if (size>12)
272  {
273  packetSize = size - 12; // 12 is the size of the SeqTsHeader
274  }
275  else
276  {
277  packetSize = 0;
278  }
279  p = Create<Packet> (packetSize);
280  SeqTsHeader seqTs;
281  seqTs.SetSeq (m_sent);
282  p->AddHeader (seqTs);
283 
284  std::stringstream addressString;
286  {
287  addressString << Ipv4Address::ConvertFrom (m_peerAddress);
288  }
289  else if (Ipv6Address::IsMatchingType(m_peerAddress) == true)
290  {
291  addressString << Ipv6Address::ConvertFrom (m_peerAddress);
292  }
293  else
294  {
295  addressString << m_peerAddress;
296  }
297 
298  if ((m_socket->Send (p)) >= 0)
299  {
300  ++m_sent;
301  NS_LOG_INFO ("Sent " << size << " bytes to "
302  << addressString.str ());
303  }
304  else
305  {
306  NS_LOG_INFO ("Error while sending " << size << " bytes to "
307  << addressString.str ());
308  }
309 }
310 
311 void
313 {
314  NS_LOG_FUNCTION (this);
315 
317  Ptr<Packet> p;
318  struct TraceEntry *entry = &m_entries[m_currentEntry];
319  do
320  {
321  for (int i = 0; i < entry->packetSize / m_maxPacketSize; i++)
322  {
324  }
325 
326  uint16_t sizetosend = entry->packetSize % m_maxPacketSize;
327  SendPacket (sizetosend);
328 
329  m_currentEntry++;
330  m_currentEntry %= m_entries.size ();
331  entry = &m_entries[m_currentEntry];
332  }
333  while (entry->timeToSend == 0);
335 }
336 
337 } // Namespace ns3