A Discrete-Event Network Simulator
API
three-gpp-http-client.cc
Go to the documentation of this file.
1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2013 Magister Solutions
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: Budiarto Herman <budiarto.herman@magister.fi>
19  *
20  */
21 
22 #include "three-gpp-http-client.h"
23 
24 #include <ns3/log.h>
25 #include <ns3/simulator.h>
26 #include <ns3/callback.h>
27 #include <ns3/pointer.h>
28 #include <ns3/uinteger.h>
29 #include <ns3/double.h>
30 #include <ns3/three-gpp-http-variables.h>
31 #include <ns3/packet.h>
32 #include <ns3/socket.h>
33 #include <ns3/tcp-socket-factory.h>
34 #include <ns3/inet-socket-address.h>
35 #include <ns3/inet6-socket-address.h>
36 
37 
38 NS_LOG_COMPONENT_DEFINE ("ThreeGppHttpClient");
39 
40 
41 namespace ns3 {
42 
43 NS_OBJECT_ENSURE_REGISTERED (ThreeGppHttpClient);
44 
45 
47  : m_state (NOT_STARTED),
48  m_socket (0),
49  m_objectBytesToBeReceived (0),
50  m_objectClientTs (MilliSeconds (0)),
51  m_objectServerTs (MilliSeconds (0)),
52  m_embeddedObjectsToBeRequested (0),
53  m_httpVariables (CreateObject<ThreeGppHttpVariables> ())
54 {
55  NS_LOG_FUNCTION (this);
56 }
57 
58 
59 // static
60 TypeId
62 {
63  static TypeId tid = TypeId ("ns3::ThreeGppHttpClient")
65  .AddConstructor<ThreeGppHttpClient> ()
66  .AddAttribute ("Variables",
67  "Variable collection, which is used to control e.g. timing and HTTP request size.",
68  PointerValue (),
70  MakePointerChecker<ThreeGppHttpVariables> ())
71  .AddAttribute ("RemoteServerAddress",
72  "The address of the destination server.",
73  AddressValue (),
76  .AddAttribute ("RemoteServerPort",
77  "The destination port of the outbound packets.",
78  UintegerValue (80), // the default HTTP port
80  MakeUintegerChecker<uint16_t> ())
81  .AddTraceSource ("ConnectionEstablished",
82  "Connection to the destination web server has been established.",
84  "ns3::ThreeGppHttpClient::TracedCallback")
85  .AddTraceSource ("ConnectionClosed",
86  "Connection to the destination web server is closed.",
88  "ns3::ThreeGppHttpClient::TracedCallback")
89  .AddTraceSource ("Tx",
90  "General trace for sending a packet of any kind.",
92  "ns3::Packet::TracedCallback")
93  .AddTraceSource ("TxMainObjectRequest",
94  "Sent a request for a main object.",
96  "ns3::Packet::TracedCallback")
97  .AddTraceSource ("TxEmbeddedObjectRequest",
98  "Sent a request for an embedded object.",
100  "ns3::Packet::TracedCallback")
101  .AddTraceSource ("RxMainObjectPacket",
102  "A packet of main object has been received.",
104  "ns3::Packet::TracedCallback")
105  .AddTraceSource ("RxMainObject",
106  "Received a whole main object. Header is included.",
108  "ns3::ThreeGppHttpClient::TracedCallback")
109  .AddTraceSource ("RxEmbeddedObjectPacket",
110  "A packet of embedded object has been received.",
112  "ns3::Packet::TracedCallback")
113  .AddTraceSource ("RxEmbeddedObject",
114  "Received a whole embedded object. Header is included.",
116  "ns3::ThreeGppHttpClient::TracedCallback")
117  .AddTraceSource ("Rx",
118  "General trace for receiving a packet of any kind.",
120  "ns3::Packet::PacketAddressTracedCallback")
121  .AddTraceSource ("RxDelay",
122  "General trace of delay for receiving a complete object.",
124  "ns3::Application::DelayAddressCallback")
125  .AddTraceSource ("RxRtt",
126  "General trace of round trip delay time for receiving a complete object.",
128  "ns3::Application::DelayAddressCallback")
129  .AddTraceSource ("StateTransition",
130  "Trace fired upon every HTTP client state transition.",
132  "ns3::Application::StateTransitionCallback")
133  ;
134  return tid;
135 }
136 
137 
140 {
141  return m_socket;
142 }
143 
144 
147 {
148  return m_state;
149 }
150 
151 
152 std::string
154 {
155  return GetStateString (m_state);
156 }
157 
158 // static
159 std::string
161 {
162  switch (state)
163  {
164  case NOT_STARTED:
165  return "NOT_STARTED";
166  break;
167  case CONNECTING:
168  return "CONNECTING";
169  break;
171  return "EXPECTING_MAIN_OBJECT";
172  break;
173  case PARSING_MAIN_OBJECT:
174  return "PARSING_MAIN_OBJECT";
175  break;
177  return "EXPECTING_EMBEDDED_OBJECT";
178  break;
179  case READING:
180  return "READING";
181  break;
182  case STOPPED:
183  return "STOPPED";
184  break;
185  default:
186  NS_FATAL_ERROR ("Unknown state");
187  return "FATAL_ERROR";
188  break;
189  }
190 }
191 
192 
193 void
195 {
196  NS_LOG_FUNCTION (this);
197 
198  if (!Simulator::IsFinished ())
199  {
200  StopApplication ();
201  }
202 
203  Application::DoDispose (); // Chain up.
204 }
205 
206 
207 void
209 {
210  NS_LOG_FUNCTION (this);
211 
212  if (m_state == NOT_STARTED)
213  {
214  m_httpVariables->Initialize ();
215  OpenConnection ();
216  }
217  else
218  {
219  NS_FATAL_ERROR ("Invalid state " << GetStateString ()
220  << " for StartApplication().");
221  }
222 }
223 
224 
225 void
227 {
228  NS_LOG_FUNCTION (this);
229 
232  m_socket->Close ();
234  MakeNullCallback<void, Ptr<Socket> > ());
236 }
237 
238 
239 void
241 {
242  NS_LOG_FUNCTION (this << socket);
243 
244  if (m_state == CONNECTING)
245  {
246  NS_ASSERT_MSG (m_socket == socket, "Invalid socket.");
249  this));
253  }
254  else
255  {
256  NS_FATAL_ERROR ("Invalid state " << GetStateString ()
257  << " for ConnectionSucceeded().");
258  }
259 }
260 
261 
262 void
264 {
265  NS_LOG_FUNCTION (this << socket);
266 
267  if (m_state == CONNECTING)
268  {
269  NS_LOG_ERROR ("Client failed to connect"
270  << " to remote address " << m_remoteServerAddress
271  << " port " << m_remoteServerPort << ".");
272  }
273  else
274  {
275  NS_FATAL_ERROR ("Invalid state " << GetStateString ()
276  << " for ConnectionFailed().");
277  }
278 }
279 
280 
281 void
283 {
284  NS_LOG_FUNCTION (this << socket);
285 
287 
288  if (socket->GetErrno () != Socket::ERROR_NOTERROR)
289  {
290  NS_LOG_ERROR (this << " Connection has been terminated,"
291  << " error code: " << socket->GetErrno () << ".");
292  }
293 
295  MakeNullCallback<void, Ptr<Socket> > ());
296 
298 }
299 
300 
301 void
303 {
304  NS_LOG_FUNCTION (this << socket);
305 
307  if (socket->GetErrno () != Socket::ERROR_NOTERROR)
308  {
309  NS_LOG_ERROR (this << " Connection has been terminated,"
310  << " error code: " << socket->GetErrno () << ".");
311  }
312 
314 }
315 
316 
317 void
319 {
320  NS_LOG_FUNCTION (this << socket);
321 
322  Ptr<Packet> packet;
323  Address from;
324 
325  while ((packet = socket->RecvFrom (from)))
326  {
327  if (packet->GetSize () == 0)
328  {
329  break; // EOF
330  }
331 
332 #ifdef NS3_LOG_ENABLE
333  // Some log messages.
335  {
336  NS_LOG_INFO (this << " A packet of " << packet->GetSize () << " bytes"
337  << " received from " << InetSocketAddress::ConvertFrom (from).GetIpv4 ()
338  << " port " << InetSocketAddress::ConvertFrom (from).GetPort ()
339  << " / " << InetSocketAddress::ConvertFrom (from) << ".");
340  }
341  else if (Inet6SocketAddress::IsMatchingType (from))
342  {
343  NS_LOG_INFO (this << " A packet of " << packet->GetSize () << " bytes"
344  << " received from " << Inet6SocketAddress::ConvertFrom (from).GetIpv6 ()
345  << " port " << Inet6SocketAddress::ConvertFrom (from).GetPort ()
346  << " / " << Inet6SocketAddress::ConvertFrom (from) << ".");
347  }
348 #endif /* NS3_LOG_ENABLE */
349 
350  m_rxTrace (packet, from);
351 
352  switch (m_state)
353  {
355  ReceiveMainObject (packet, from);
356  break;
358  ReceiveEmbeddedObject (packet, from);
359  break;
360  default:
361  NS_FATAL_ERROR ("Invalid state " << GetStateString ()
362  << " for ReceivedData().");
363  break;
364  }
365 
366  } // end of `while ((packet = socket->RecvFrom (from)))`
367 
368 } // end of `void ReceivedDataCallback (Ptr<Socket> socket)`
369 
370 
371 void
373 {
374  NS_LOG_FUNCTION (this);
375 
378  {
381 
382  [[maybe_unused]] int ret;
383 
385  {
386  ret = m_socket->Bind ();
387  NS_LOG_DEBUG (this << " Bind() return value= " << ret
388  << " GetErrNo= " << m_socket->GetErrno () << ".");
389 
391  InetSocketAddress inetSocket = InetSocketAddress (ipv4,
393  NS_LOG_INFO (this << " Connecting to " << ipv4
394  << " port " << m_remoteServerPort
395  << " / " << inetSocket << ".");
396  ret = m_socket->Connect (inetSocket);
397  NS_LOG_DEBUG (this << " Connect() return value= " << ret
398  << " GetErrNo= " << m_socket->GetErrno () << ".");
399  }
401  {
402  ret = m_socket->Bind6 ();
403  NS_LOG_DEBUG (this << " Bind6() return value= " << ret
404  << " GetErrNo= " << m_socket->GetErrno () << ".");
405 
407  Inet6SocketAddress inet6Socket = Inet6SocketAddress (ipv6,
409  NS_LOG_INFO (this << " connecting to " << ipv6
410  << " port " << m_remoteServerPort
411  << " / " << inet6Socket << ".");
412  ret = m_socket->Connect (inet6Socket);
413  NS_LOG_DEBUG (this << " Connect() return value= " << ret
414  << " GetErrNo= " << m_socket->GetErrno () << ".");
415  }
416 
417  NS_ASSERT_MSG (m_socket != 0, "Failed creating socket.");
418 
420 
422  this),
424  this));
426  this),
428  this));
430  this));
431  m_socket->SetAttribute ("MaxSegLifetime", DoubleValue (0.02)); // 20 ms.
432 
433  } // end of `if (m_state == {NOT_STARTED, EXPECTING_EMBEDDED_OBJECT, PARSING_MAIN_OBJECT, READING})`
434  else
435  {
436  NS_FATAL_ERROR ("Invalid state " << GetStateString ()
437  << " for OpenConnection().");
438  }
439 
440 } // end of `void OpenConnection ()`
441 
442 
443 void
445 {
446  NS_LOG_FUNCTION (this);
447 
448  if (m_state == CONNECTING || m_state == READING)
449  {
450  ThreeGppHttpHeader header;
451  header.SetContentLength (0); // Request does not need any content length.
453  header.SetClientTs (Simulator::Now ());
454 
455  const uint32_t requestSize = m_httpVariables->GetRequestSize ();
456  Ptr<Packet> packet = Create<Packet> (requestSize);
457  packet->AddHeader (header);
458  const uint32_t packetSize = packet->GetSize ();
460  m_txTrace (packet);
461  const int actualBytes = m_socket->Send (packet);
462  NS_LOG_DEBUG (this << " Send() packet " << packet
463  << " of " << packet->GetSize () << " bytes,"
464  << " return value= " << actualBytes << ".");
465  if (actualBytes != static_cast<int> (packetSize))
466  {
467  NS_LOG_ERROR (this << " Failed to send request for embedded object,"
468  << " GetErrNo= " << m_socket->GetErrno () << ","
469  << " waiting for another Tx opportunity.");
470  }
471  else
472  {
474  }
475  }
476  else
477  {
478  NS_FATAL_ERROR ("Invalid state " << GetStateString ()
479  << " for RequestMainObject().");
480  }
481 
482 } // end of `void RequestMainObject ()`
483 
484 
485 void
487 {
488  NS_LOG_FUNCTION (this);
489 
492  {
494  {
495  ThreeGppHttpHeader header;
496  header.SetContentLength (0); // Request does not need any content length.
498  header.SetClientTs (Simulator::Now ());
499 
500  const uint32_t requestSize = m_httpVariables->GetRequestSize ();
501  Ptr<Packet> packet = Create<Packet> (requestSize);
502  packet->AddHeader (header);
503  const uint32_t packetSize = packet->GetSize ();
505  m_txTrace (packet);
506  const int actualBytes = m_socket->Send (packet);
507  NS_LOG_DEBUG (this << " Send() packet " << packet
508  << " of " << packet->GetSize () << " bytes,"
509  << " return value= " << actualBytes << ".");
510 
511  if (actualBytes != static_cast<int> (packetSize))
512  {
513  NS_LOG_ERROR (this << " Failed to send request for embedded object,"
514  << " GetErrNo= " << m_socket->GetErrno () << ","
515  << " waiting for another Tx opportunity.");
516  }
517  else
518  {
521  }
522  }
523  else
524  {
525  NS_LOG_WARN (this << " No embedded object to be requested.");
526  }
527  }
528  else
529  {
530  NS_FATAL_ERROR ("Invalid state " << GetStateString ()
531  << " for RequestEmbeddedObject().");
532  }
533 
534 } // end of `void RequestEmbeddedObject ()`
535 
536 
537 void
539 {
540  NS_LOG_FUNCTION (this << packet << from);
541 
543  {
544  /*
545  * In the following call to Receive(), #m_objectBytesToBeReceived *will*
546  * be updated. #m_objectClientTs and #m_objectServerTs *may* be updated.
547  * ThreeGppHttpHeader will be removed from the packet, if it is the first
548  * packet of the object to be received; the header will be available in
549  * #m_constructedPacketHeader.
550  * #m_constructedPacket will also be updated.
551  */
552  Receive (packet);
553  m_rxMainObjectPacketTrace (packet);
554 
556  {
557  /*
558  * There are more packets of this main object, so just stay still
559  * and wait until they arrive.
560  */
561  NS_LOG_INFO (this << " " << m_objectBytesToBeReceived << " byte(s)"
562  << " remains from this chunk of main object.");
563  }
564  else
565  {
566  /*
567  * This is the last packet of this main object. Acknowledge the
568  * reception of a whole main object
569  */
570  NS_LOG_INFO (this << " Finished receiving a main object.");
572 
573  if (!m_objectServerTs.IsZero ())
574  {
576  m_objectServerTs = MilliSeconds (0); // Reset back to zero.
577  }
578 
579  if (!m_objectClientTs.IsZero ())
580  {
582  m_objectClientTs = MilliSeconds (0); // Reset back to zero.
583  }
584 
585  EnterParsingTime ();
586 
587  } // end of else of `if (m_objectBytesToBeReceived > 0)`
588 
589  } // end of `if (m_state == EXPECTING_MAIN_OBJECT)`
590  else
591  {
592  NS_FATAL_ERROR ("Invalid state " << GetStateString ()
593  << " for ReceiveMainObject().");
594  }
595 
596 } // end of `void ReceiveMainObject (Ptr<Packet> packet)`
597 
598 
599 void
601 {
602  NS_LOG_FUNCTION (this << packet << from);
603 
605  {
606  /*
607  * In the following call to Receive(), #m_objectBytesToBeReceived *will*
608  * be updated. #m_objectClientTs and #m_objectServerTs *may* be updated.
609  * ThreeGppHttpHeader will be removed from the packet, if it is the first
610  * packet of the object to be received; the header will be available in
611  * #m_constructedPacket, which will also be updated.
612  */
613  Receive (packet);
615 
617  {
618  /*
619  * There are more packets of this embedded object, so just stay
620  * still and wait until they arrive.
621  */
622  NS_LOG_INFO (this << " " << m_objectBytesToBeReceived << " byte(s)"
623  << " remains from this chunk of embedded object");
624  }
625  else
626  {
627  /*
628  * This is the last packet of this embedded object. Acknowledge
629  * the reception of a whole embedded object
630  */
631  NS_LOG_INFO (this << " Finished receiving an embedded object.");
633 
634  if (!m_objectServerTs.IsZero ())
635  {
637  m_objectServerTs = MilliSeconds (0); // Reset back to zero.
638  }
639 
640  if (!m_objectClientTs.IsZero ())
641  {
643  m_objectClientTs = MilliSeconds (0); // Reset back to zero.
644  }
645 
647  {
649  << " more embedded object(s) to be requested.");
650  // Immediately request another using the existing connection.
653  }
654  else
655  {
656  /*
657  * There is no more embedded object, the web page has been
658  * downloaded completely. Now is the time to read it.
659  */
660  NS_LOG_INFO (this << " Finished receiving a web page.");
661  EnterReadingTime ();
662  }
663 
664  } // end of else of `if (m_objectBytesToBeReceived > 0)`
665 
666  } // end of `if (m_state == EXPECTING_EMBEDDED_OBJECT)`
667  else
668  {
669  NS_FATAL_ERROR ("Invalid state " << GetStateString ()
670  << " for ReceiveEmbeddedObject().");
671  }
672 
673 } // end of `void ReceiveEmbeddedObject (Ptr<Packet> packet)`
674 
675 
676 void
678 {
679  NS_LOG_FUNCTION (this << packet);
680 
681  /* In a "real" HTTP message the message size is coded differently. The use of a header
682  * is to avoid the burden of doing a real message parser.
683  */
684  bool firstPacket = false;
685 
686  if (m_objectBytesToBeReceived == 0)
687  {
688  // This is the first packet of the object.
689  firstPacket = true;
690 
691  // Remove the header in order to calculate remaining data to be received.
692  ThreeGppHttpHeader httpHeader;
693  packet->RemoveHeader (httpHeader);
694 
696  m_objectClientTs = httpHeader.GetClientTs ();
697  m_objectServerTs = httpHeader.GetServerTs ();
698 
699  // Take a copy for constructed packet trace. Note that header is included.
700  m_constructedPacket = packet->Copy ();
701  m_constructedPacket->AddHeader (httpHeader);
702  }
703  uint32_t contentSize = packet->GetSize ();
704 
705  /* Note that the packet does not contain header at this point.
706  * The content is purely raw data, which was the only intended data to be received.
707  */
708  if (m_objectBytesToBeReceived < contentSize)
709  {
710  NS_LOG_WARN (this << " The received packet"
711  << " (" << contentSize << " bytes of content)"
712  << " is larger than"
713  << " the content that we expected to receive"
714  << " (" << m_objectBytesToBeReceived << " bytes).");
715  // Stop expecting any more packet of this object.
717  m_constructedPacket = NULL;
718  }
719  else
720  {
721  m_objectBytesToBeReceived -= contentSize;
722  if (!firstPacket)
723  {
724  Ptr<Packet> packetCopy = packet->Copy ();
725  m_constructedPacket->AddAtEnd (packetCopy);
726  }
727  }
728 
729 } // end of `void Receive (packet)`
730 
731 
732 void
734 {
735  NS_LOG_FUNCTION (this);
736 
738  {
739  const Time parsingTime = m_httpVariables->GetParsingTime ();
740  NS_LOG_INFO (this << " The parsing of this main object"
741  << " will complete in "
742  << parsingTime.As (Time::S) << ".");
744  parsingTime, &ThreeGppHttpClient::ParseMainObject, this);
746  }
747  else
748  {
749  NS_FATAL_ERROR ("Invalid state " << GetStateString ()
750  << " for EnterParsingTime().");
751  }
752 }
753 
754 
755 void
757 {
758  NS_LOG_FUNCTION (this);
759 
761  {
762  m_embeddedObjectsToBeRequested = m_httpVariables->GetNumOfEmbeddedObjects ();
763  NS_LOG_INFO (this << " Parsing has determined "
765  << " embedded object(s) in the main object.");
766 
768  {
769  /*
770  * Immediately request the first embedded object using the
771  * existing connection.
772  */
775  }
776  else
777  {
778  /*
779  * There is no embedded object in the main object. So sit back and
780  * enjoy the plain web page.
781  */
782  NS_LOG_INFO (this << " Finished receiving a web page.");
783  EnterReadingTime ();
784  }
785 
786  }
787  else
788  {
789  NS_FATAL_ERROR ("Invalid state " << GetStateString ()
790  << " for ParseMainObject().");
791  }
792 
793 } // end of `void ParseMainObject ()`
794 
795 
796 void
798 {
799  NS_LOG_FUNCTION (this);
800 
802  {
803  const Time readingTime = m_httpVariables->GetReadingTime ();
804  NS_LOG_INFO (this << " Client will finish reading this web page in "
805  << readingTime.As (Time::S) << ".");
806 
807  // Schedule a request of another main object once the reading time expires.
809  readingTime, &ThreeGppHttpClient::RequestMainObject, this);
811  }
812  else
813  {
814  NS_FATAL_ERROR ("Invalid state " << GetStateString ()
815  << " for EnterReadingTime().");
816  }
817 }
818 
819 
820 void
822 {
823  NS_LOG_FUNCTION (this);
824 
826  {
827  NS_LOG_INFO (this << " Canceling RequestMainObject() which is due in "
829  << ".");
831  }
832 
834  {
835  NS_LOG_INFO (this << " Canceling RequestEmbeddedObject() which is due in "
837  << ".");
839  }
840 
842  {
843  NS_LOG_INFO (this << " Canceling ParseMainObject() which is due in "
845  << ".");
847  }
848 }
849 
850 
851 void
853 {
854  const std::string oldState = GetStateString ();
855  const std::string newState = GetStateString (state);
856  NS_LOG_FUNCTION (this << oldState << newState);
857 
858  if ((state == EXPECTING_MAIN_OBJECT) || (state == EXPECTING_EMBEDDED_OBJECT))
859  {
861  {
862  NS_FATAL_ERROR ("Cannot start a new receiving session"
863  << " if the previous object"
864  << " (" << m_objectBytesToBeReceived << " bytes)"
865  << " is not completely received yet.");
866  }
867  }
868 
869  m_state = state;
870  NS_LOG_INFO (this << " HttpClient " << oldState
871  << " --> " << newState << ".");
872  m_stateTransitionTrace (oldState, newState);
873 }
874 
875 
876 } // end of `namespace ns3`
877 
a polymophic address class
Definition: address.h:91
AttributeValue implementation for Address.
Definition: address.h:278
The base class for all ns3 applications.
Definition: application.h:61
virtual void DoDispose(void)
Destructor implementation.
Definition: application.cc:83
Ptr< Node > GetNode() const
Definition: application.cc:104
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:41
An Inet6 address class.
static Inet6SocketAddress ConvertFrom(const Address &addr)
Convert the address to a InetSocketAddress.
static bool IsMatchingType(const Address &addr)
If the address match.
Ipv6Address GetIpv6(void) const
Get the IPv6 address.
uint16_t GetPort(void) const
Get the port.
an Inet address class
uint16_t GetPort(void) const
Ipv4Address GetIpv4(void) const
static bool IsMatchingType(const Address &address)
static InetSocketAddress ConvertFrom(const Address &address)
Returns an InetSocketAddress which corresponds to the input Address.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:41
static Ipv4Address ConvertFrom(const Address &address)
static bool IsMatchingType(const Address &address)
Describes an IPv6 address.
Definition: ipv6-address.h:50
static Ipv6Address ConvertFrom(const Address &address)
Convert the Address object into an Ipv6Address ones.
static bool IsMatchingType(const Address &address)
If the Address matches the type.
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:256
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:280
void AddAtEnd(Ptr< const Packet > packet)
Concatenate the input packet at the end of the current packet.
Definition: packet.cc:335
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:256
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Definition: packet.cc:121
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:856
Hold objects of type Ptr<T>.
Definition: pointer.h:37
static void Cancel(const EventId &id)
Set the cancel bit on this event: the event's associated function will not be invoked when it expires...
Definition: simulator.cc:268
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:556
static bool IsExpired(const EventId &id)
Check if an event has already run or been cancelled.
Definition: simulator.cc:278
static bool IsFinished(void)
Check if the simulation should finish.
Definition: simulator.cc:165
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition: simulator.h:587
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:195
static Time GetDelayLeft(const EventId &id)
Get the remaining time until this event will execute.
Definition: simulator.cc:204
virtual int Send(Ptr< Packet > p, uint32_t flags)=0
Send data (or dummy data) to the remote host.
void SetConnectCallback(Callback< void, Ptr< Socket > > connectionSucceeded, Callback< void, Ptr< Socket > > connectionFailed)
Specify callbacks to allow the caller to determine if the connection succeeds of fails.
Definition: socket.cc:84
virtual int Bind6()=0
Allocate a local IPv6 endpoint for this socket.
virtual int Connect(const Address &address)=0
Initiate a connection to a remote host.
virtual int Close(void)=0
Close a socket.
void SetCloseCallbacks(Callback< void, Ptr< Socket > > normalClose, Callback< void, Ptr< Socket > > errorClose)
Detect socket recv() events such as graceful shutdown or error.
Definition: socket.cc:94
void SetRecvCallback(Callback< void, Ptr< Socket > > receivedData)
Notify application when new data is available to be read.
Definition: socket.cc:128
static Ptr< Socket > CreateSocket(Ptr< Node > node, TypeId tid)
This method wraps the creation of sockets that is performed on a given node by a SocketFactory specif...
Definition: socket.cc:71
@ ERROR_NOTERROR
Definition: socket.h:83
virtual int Bind(const Address &address)=0
Allocate a local endpoint for this socket.
virtual enum Socket::SocketErrno GetErrno(void) const =0
Get last error number.
virtual Ptr< Packet > RecvFrom(uint32_t maxSize, uint32_t flags, Address &fromAddress)=0
Read a single packet from the socket and retrieve the sender address.
static TypeId GetTypeId(void)
Get the type ID.
virtual void StartApplication()
Application specific startup code.
void ReceiveMainObject(Ptr< Packet > packet, const Address &from)
Receive a packet of main object from the destination web server.
ns3::TracedCallback< Ptr< const ThreeGppHttpClient > > m_connectionClosedTrace
The ConnectionClosed trace source.
ns3::TracedCallback< Ptr< const ThreeGppHttpClient >, Ptr< const Packet > > m_rxEmbeddedObjectTrace
The TxEmbeddedObject trace source.
Ptr< ThreeGppHttpVariables > m_httpVariables
The Variables attribute.
uint32_t m_embeddedObjectsToBeRequested
Determined after parsing the main object.
EventId m_eventParseMainObject
An event of ParseMainObject(), scheduled to trigger after parsing time has elapsed.
void SwitchToState(State_t state)
Change the state of the client.
void ConnectionFailedCallback(Ptr< Socket > socket)
Invoked when m_socket cannot establish a connection with the web server.
ns3::TracedCallback< Ptr< const Packet >, const Address & > m_rxTrace
The Rx trace source.
ThreeGppHttpClient()
Creates a new instance of HTTP client application.
void EnterParsingTime()
Becomes idle for a randomly determined amount of time, and then triggers ParseMainObject().
State_t m_state
The current state of the client application. Begins with NOT_STARTED.
Ptr< Socket > m_socket
The socket for sending and receiving packets to/from the web server.
void RequestEmbeddedObject()
Send a request object for an embedded object to the destination web server.
void ParseMainObject()
Randomly determines the number of embedded objects in the main object.
ns3::TracedCallback< Ptr< const ThreeGppHttpClient >, Ptr< const Packet > > m_rxMainObjectTrace
The TxMainObject trace source.
State_t GetState() const
Returns the current state of the application.
ns3::TracedCallback< const Time &, const Address & > m_rxRttTrace
The RxRtt trace source.
void EnterReadingTime()
Becomes idle for a randomly determined amount of time, and then triggers RequestMainObject().
ns3::TracedCallback< const std::string &, const std::string & > m_stateTransitionTrace
The StateTransition trace source.
Ptr< Packet > m_constructedPacket
The packet constructed of one or more parts with ThreeGppHttpHeader.
uint32_t m_objectBytesToBeReceived
According to the content length specified by the ThreeGppHttpHeader.
virtual void StopApplication()
Application specific shutdown code.
void ConnectionSucceededCallback(Ptr< Socket > socket)
Invoked when a connection is established successfully on m_socket.
static TypeId GetTypeId()
Returns the object TypeId.
void ErrorCloseCallback(Ptr< Socket > socket)
Invoked when connection between m_socket and the web sever is terminated.
EventId m_eventRequestMainObject
An event of either RequestMainObject() or OpenConnection(), scheduled to trigger after a connection h...
uint16_t m_remoteServerPort
The RemoteServerPort attribute.
Address m_remoteServerAddress
The RemoteServerAddress attribute. The address of the web server.
virtual void DoDispose()
Destructor implementation.
void CancelAllPendingEvents()
Cancels m_eventRequestMainObject, m_eventRequestEmbeddedObject, and m_eventParseMainObject.
Ptr< Socket > GetSocket() const
Returns a pointer to the associated socket.
ns3::TracedCallback< Ptr< const Packet > > m_txTrace
The Tx trace source.
Time m_objectClientTs
The client time stamp of the ThreeGppHttpHeader from the last received packet.
State_t
The possible states of the application.
@ CONNECTING
Sent the server a connection request and waiting for the server to be accept it.
@ NOT_STARTED
Before StartApplication() is invoked.
@ READING
User reading a web page that has just been received.
@ EXPECTING_MAIN_OBJECT
Sent the server a request for a main object and waiting to receive the packets.
@ STOPPED
After StopApplication() is invoked.
@ PARSING_MAIN_OBJECT
Parsing a main object that has just been received.
@ EXPECTING_EMBEDDED_OBJECT
Sent the server a request for an embedded object and waiting to receive the packets.
ns3::TracedCallback< Ptr< const Packet > > m_txMainObjectRequestTrace
The TxMainObjectRequest trace source.
ns3::TracedCallback< Ptr< const Packet > > m_rxMainObjectPacketTrace
The TxMainObjectPacket trace source.
void RequestMainObject()
Send a request object for a main object to the destination web server.
Time m_objectServerTs
The server time stamp of the ThreeGppHttpHeader from the last received packet.
void NormalCloseCallback(Ptr< Socket > socket)
Invoked when connection between m_socket and the web sever is terminated.
ns3::TracedCallback< Ptr< const ThreeGppHttpClient > > m_connectionEstablishedTrace
The ConnectionEstablished trace source.
ns3::TracedCallback< Ptr< const Packet > > m_txEmbeddedObjectRequestTrace
The TxEmbeddedObjectRequest trace source.
void ReceivedDataCallback(Ptr< Socket > socket)
Invoked when m_socket receives some packet data.
ns3::TracedCallback< const Time &, const Address & > m_rxDelayTrace
The RxDelay trace source.
ns3::TracedCallback< Ptr< const Packet > > m_rxEmbeddedObjectPacketTrace
The TxEmbeddedObjectPacket trace source.
void Receive(Ptr< Packet > packet)
Simulate a consumption of the received packet by subtracting the packet size from the internal counte...
void ReceiveEmbeddedObject(Ptr< Packet > packet, const Address &from)
Receive a packet of embedded object from the destination web server.
void OpenConnection()
Initialize m_socket to connect to the destination web server at m_remoteServerAddress and m_remoteSer...
std::string GetStateString() const
Returns the current state of the application in string format.
EventId m_eventRequestEmbeddedObject
An event of either RequestEmbeddedObject() or OpenConnection().
Header used by web browsing applications to transmit information about content type,...
void SetClientTs(Time clientTs)
void SetContentLength(uint32_t contentLength)
void SetContentType(ContentType_t contentType)
@ EMBEDDED_OBJECT
Integer equivalent = 2.
@ MAIN_OBJECT
Integer equivalent = 1.
Container of various random variables to assist in generating web browsing traffic pattern.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
@ S
second
Definition: nstime.h:114
bool IsZero(void) const
Exactly equivalent to t == 0.
Definition: nstime.h:300
TimeWithUnit As(const enum Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:418
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:922
Hold an unsigned integer type.
Definition: uinteger.h:44
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:67
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:88
Ptr< const AttributeAccessor > MakeAddressAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: address.h:278
Ptr< const AttributeChecker > MakeAddressChecker(void)
Definition: address.cc:172
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: pointer.h:227
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: uinteger.h:45
Callback< R, Ts... > MakeNullCallback(void)
Definition: callback.h:1688
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:165
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:257
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:265
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:281
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition: object.h:576
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1252
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Ts... > MakeCallback(R(T::*memPtr)(Ts...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:1648
static const uint32_t packetSize