A Discrete-Event Network Simulator
API
three-gpp-http-client.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 Magister Solutions
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Budiarto Herman <budiarto.herman@magister.fi>
18  *
19  */
20 
21 #include "three-gpp-http-client.h"
22 
24 
25 #include <ns3/callback.h>
26 #include <ns3/double.h>
27 #include <ns3/inet-socket-address.h>
28 #include <ns3/inet6-socket-address.h>
29 #include <ns3/log.h>
30 #include <ns3/packet.h>
31 #include <ns3/pointer.h>
32 #include <ns3/simulator.h>
33 #include <ns3/socket.h>
34 #include <ns3/tcp-socket-factory.h>
35 #include <ns3/uinteger.h>
36 
37 NS_LOG_COMPONENT_DEFINE("ThreeGppHttpClient");
38 
39 namespace ns3
40 {
41 
42 NS_OBJECT_ENSURE_REGISTERED(ThreeGppHttpClient);
43 
45  : m_state(NOT_STARTED),
46  m_socket(nullptr),
47  m_objectBytesToBeReceived(0),
48  m_objectClientTs(MilliSeconds(0)),
49  m_objectServerTs(MilliSeconds(0)),
50  m_embeddedObjectsToBeRequested(0),
51  m_pageLoadStartTs(MilliSeconds(0)),
52  m_numberEmbeddedObjectsRequested(0),
53  m_numberBytesPage(0),
54  m_httpVariables(CreateObject<ThreeGppHttpVariables>())
55 {
56  NS_LOG_FUNCTION(this);
57 }
58 
59 // static
60 TypeId
62 {
63  static TypeId tid =
64  TypeId("ns3::ThreeGppHttpClient")
66  .AddConstructor<ThreeGppHttpClient>()
67  .AddAttribute(
68  "Variables",
69  "Variable collection, which is used to control e.g. timing and HTTP request size.",
70  PointerValue(),
72  MakePointerChecker<ThreeGppHttpVariables>())
73  .AddAttribute("RemoteServerAddress",
74  "The address of the destination server.",
75  AddressValue(),
76  MakeAddressAccessor(&ThreeGppHttpClient::m_remoteServerAddress),
77  MakeAddressChecker())
78  .AddAttribute("RemoteServerPort",
79  "The destination port of the outbound packets.",
80  UintegerValue(80), // the default HTTP port
82  MakeUintegerChecker<uint16_t>())
83  .AddTraceSource("RxPage",
84  "A page has been received.",
86  "ns3::ThreeGppHttpClient::RxPageTracedCallback")
87  .AddTraceSource(
88  "ConnectionEstablished",
89  "Connection to the destination web server has been established.",
91  "ns3::ThreeGppHttpClient::TracedCallback")
92  .AddTraceSource("ConnectionClosed",
93  "Connection to the destination web server is closed.",
95  "ns3::ThreeGppHttpClient::TracedCallback")
96  .AddTraceSource("Tx",
97  "General trace for sending a packet of any kind.",
99  "ns3::Packet::TracedCallback")
100  .AddTraceSource(
101  "TxMainObjectRequest",
102  "Sent a request for a main object.",
104  "ns3::Packet::TracedCallback")
105  .AddTraceSource(
106  "TxEmbeddedObjectRequest",
107  "Sent a request for an embedded object.",
109  "ns3::Packet::TracedCallback")
110  .AddTraceSource("RxMainObjectPacket",
111  "A packet of main object has been received.",
113  "ns3::Packet::TracedCallback")
114  .AddTraceSource("RxMainObject",
115  "Received a whole main object. Header is included.",
117  "ns3::ThreeGppHttpClient::TracedCallback")
118  .AddTraceSource(
119  "RxEmbeddedObjectPacket",
120  "A packet of embedded object has been received.",
122  "ns3::Packet::TracedCallback")
123  .AddTraceSource("RxEmbeddedObject",
124  "Received a whole embedded object. Header is included.",
126  "ns3::ThreeGppHttpClient::TracedCallback")
127  .AddTraceSource("Rx",
128  "General trace for receiving a packet of any kind.",
130  "ns3::Packet::PacketAddressTracedCallback")
131  .AddTraceSource("RxDelay",
132  "General trace of delay for receiving a complete object.",
134  "ns3::Application::DelayAddressCallback")
135  .AddTraceSource(
136  "RxRtt",
137  "General trace of round trip delay time for receiving a complete object.",
139  "ns3::Application::DelayAddressCallback")
140  .AddTraceSource("StateTransition",
141  "Trace fired upon every HTTP client state transition.",
143  "ns3::Application::StateTransitionCallback");
144  return tid;
145 }
146 
149 {
150  return m_socket;
151 }
152 
155 {
156  return m_state;
157 }
158 
159 std::string
161 {
162  return GetStateString(m_state);
163 }
164 
165 // static
166 std::string
168 {
169  switch (state)
170  {
171  case NOT_STARTED:
172  return "NOT_STARTED";
173  case CONNECTING:
174  return "CONNECTING";
176  return "EXPECTING_MAIN_OBJECT";
177  case PARSING_MAIN_OBJECT:
178  return "PARSING_MAIN_OBJECT";
180  return "EXPECTING_EMBEDDED_OBJECT";
181  case READING:
182  return "READING";
183  case STOPPED:
184  return "STOPPED";
185  default:
186  NS_FATAL_ERROR("Unknown state");
187  return "FATAL_ERROR";
188  }
189 }
190 
191 void
193 {
194  NS_LOG_FUNCTION(this);
195 
196  if (!Simulator::IsFinished())
197  {
198  StopApplication();
199  }
200 
201  Application::DoDispose(); // Chain up.
202 }
203 
204 void
206 {
207  NS_LOG_FUNCTION(this);
208 
209  if (m_state == NOT_STARTED)
210  {
211  m_httpVariables->Initialize();
212  OpenConnection();
213  }
214  else
215  {
216  NS_FATAL_ERROR("Invalid state " << GetStateString() << " for StartApplication().");
217  }
218 }
219 
220 void
222 {
223  NS_LOG_FUNCTION(this);
224 
227  m_socket->Close();
229  MakeNullCallback<void, Ptr<Socket>>());
231 }
232 
233 void
235 {
236  NS_LOG_FUNCTION(this << socket);
237 
238  if (m_state == CONNECTING)
239  {
240  NS_ASSERT_MSG(m_socket == socket, "Invalid socket.");
246  }
247  else
248  {
249  NS_FATAL_ERROR("Invalid state " << GetStateString() << " for ConnectionSucceeded().");
250  }
251 }
252 
253 void
255 {
256  NS_LOG_FUNCTION(this << socket);
257 
258  if (m_state == CONNECTING)
259  {
260  NS_LOG_ERROR("Client failed to connect"
261  << " to remote address " << m_remoteServerAddress << " port "
262  << m_remoteServerPort << ".");
263  }
264  else
265  {
266  NS_FATAL_ERROR("Invalid state " << GetStateString() << " for ConnectionFailed().");
267  }
268 }
269 
270 void
272 {
273  NS_LOG_FUNCTION(this << socket);
274 
276 
277  if (socket->GetErrno() != Socket::ERROR_NOTERROR)
278  {
279  NS_LOG_ERROR(this << " Connection has been terminated,"
280  << " error code: " << socket->GetErrno() << ".");
281  }
282 
284  MakeNullCallback<void, Ptr<Socket>>());
285 
287 }
288 
289 void
291 {
292  NS_LOG_FUNCTION(this << socket);
293 
295  if (socket->GetErrno() != Socket::ERROR_NOTERROR)
296  {
297  NS_LOG_ERROR(this << " Connection has been terminated,"
298  << " error code: " << socket->GetErrno() << ".");
299  }
300 
302 }
303 
304 void
306 {
307  NS_LOG_FUNCTION(this << socket);
308 
309  Ptr<Packet> packet;
310  Address from;
311 
312  while ((packet = socket->RecvFrom(from)))
313  {
314  if (packet->GetSize() == 0)
315  {
316  break; // EOF
317  }
318 
319 #ifdef NS3_LOG_ENABLE
320  // Some log messages.
322  {
323  NS_LOG_INFO(this << " A packet of " << packet->GetSize() << " bytes"
324  << " received from " << InetSocketAddress::ConvertFrom(from).GetIpv4()
325  << " port " << InetSocketAddress::ConvertFrom(from).GetPort() << " / "
326  << InetSocketAddress::ConvertFrom(from) << ".");
327  }
328  else if (Inet6SocketAddress::IsMatchingType(from))
329  {
330  NS_LOG_INFO(this << " A packet of " << packet->GetSize() << " bytes"
331  << " received from " << Inet6SocketAddress::ConvertFrom(from).GetIpv6()
332  << " port " << Inet6SocketAddress::ConvertFrom(from).GetPort() << " / "
333  << Inet6SocketAddress::ConvertFrom(from) << ".");
334  }
335 #endif /* NS3_LOG_ENABLE */
336 
337  m_rxTrace(packet, from);
338 
339  switch (m_state)
340  {
342  ReceiveMainObject(packet, from);
343  break;
345  ReceiveEmbeddedObject(packet, from);
346  break;
347  default:
348  NS_FATAL_ERROR("Invalid state " << GetStateString() << " for ReceivedData().");
349  break;
350  }
351 
352  } // end of `while ((packet = socket->RecvFrom (from)))`
353 
354 } // end of `void ReceivedDataCallback (Ptr<Socket> socket)`
355 
356 void
358 {
359  NS_LOG_FUNCTION(this);
360 
363  {
365 
367  {
368  int ret [[maybe_unused]];
369 
370  ret = m_socket->Bind();
371  NS_LOG_DEBUG(this << " Bind() return value= " << ret
372  << " GetErrNo= " << m_socket->GetErrno() << ".");
373 
376  NS_LOG_INFO(this << " Connecting to " << ipv4 << " port " << m_remoteServerPort << " / "
377  << inetSocket << ".");
378  ret = m_socket->Connect(inetSocket);
379  NS_LOG_DEBUG(this << " Connect() return value= " << ret
380  << " GetErrNo= " << m_socket->GetErrno() << ".");
381  }
383  {
384  int ret [[maybe_unused]];
385 
386  ret = m_socket->Bind6();
387  NS_LOG_DEBUG(this << " Bind6() return value= " << ret
388  << " GetErrNo= " << m_socket->GetErrno() << ".");
389 
392  NS_LOG_INFO(this << " connecting to " << ipv6 << " port " << m_remoteServerPort << " / "
393  << inet6Socket << ".");
394  ret = m_socket->Connect(inet6Socket);
395  NS_LOG_DEBUG(this << " Connect() return value= " << ret
396  << " GetErrNo= " << m_socket->GetErrno() << ".");
397  }
398 
399  NS_ASSERT_MSG(m_socket, "Failed creating socket.");
400 
402 
409  m_socket->SetAttribute("MaxSegLifetime", DoubleValue(0.02)); // 20 ms.
410 
411  } // end of `if (m_state == {NOT_STARTED, EXPECTING_EMBEDDED_OBJECT, PARSING_MAIN_OBJECT,
412  // READING})`
413  else
414  {
415  NS_FATAL_ERROR("Invalid state " << GetStateString() << " for OpenConnection().");
416  }
417 
418 } // end of `void OpenConnection ()`
419 
420 void
422 {
423  NS_LOG_FUNCTION(this);
424 
425  if (m_state == CONNECTING || m_state == READING)
426  {
427  ThreeGppHttpHeader header;
428  header.SetContentLength(0); // Request does not need any content length.
430  header.SetClientTs(Simulator::Now());
431 
432  const uint32_t requestSize = m_httpVariables->GetRequestSize();
433  Ptr<Packet> packet = Create<Packet>(requestSize);
434  packet->AddHeader(header);
435  const uint32_t packetSize = packet->GetSize();
437  m_txTrace(packet);
438  const int actualBytes = m_socket->Send(packet);
439  NS_LOG_DEBUG(this << " Send() packet " << packet << " of " << packet->GetSize() << " bytes,"
440  << " return value= " << actualBytes << ".");
441  if (actualBytes != static_cast<int>(packetSize))
442  {
443  NS_LOG_ERROR(this << " Failed to send request for embedded object,"
444  << " GetErrNo= " << m_socket->GetErrno() << ","
445  << " waiting for another Tx opportunity.");
446  }
447  else
448  {
450  m_pageLoadStartTs = Simulator::Now(); // start counting page loading time
451  }
452  }
453  else
454  {
455  NS_FATAL_ERROR("Invalid state " << GetStateString() << " for RequestMainObject().");
456  }
457 
458 } // end of `void RequestMainObject ()`
459 
460 void
462 {
463  NS_LOG_FUNCTION(this);
464 
467  {
469  {
470  ThreeGppHttpHeader header;
471  header.SetContentLength(0); // Request does not need any content length.
473  header.SetClientTs(Simulator::Now());
474 
475  const uint32_t requestSize = m_httpVariables->GetRequestSize();
476  Ptr<Packet> packet = Create<Packet>(requestSize);
477  packet->AddHeader(header);
478  const uint32_t packetSize = packet->GetSize();
480  m_txTrace(packet);
481  const int actualBytes = m_socket->Send(packet);
482  NS_LOG_DEBUG(this << " Send() packet " << packet << " of " << packet->GetSize()
483  << " bytes,"
484  << " return value= " << actualBytes << ".");
485 
486  if (actualBytes != static_cast<int>(packetSize))
487  {
488  NS_LOG_ERROR(this << " Failed to send request for embedded object,"
489  << " GetErrNo= " << m_socket->GetErrno() << ","
490  << " waiting for another Tx opportunity.");
491  }
492  else
493  {
496  }
497  }
498  else
499  {
500  NS_LOG_WARN(this << " No embedded object to be requested.");
501  }
502  }
503  else
504  {
505  NS_FATAL_ERROR("Invalid state " << GetStateString() << " for RequestEmbeddedObject().");
506  }
507 
508 } // end of `void RequestEmbeddedObject ()`
509 
510 void
512 {
513  NS_LOG_FUNCTION(this << packet << from);
514 
516  {
517  /*
518  * In the following call to Receive(), #m_objectBytesToBeReceived *will*
519  * be updated. #m_objectClientTs and #m_objectServerTs *may* be updated.
520  * ThreeGppHttpHeader will be removed from the packet, if it is the first
521  * packet of the object to be received; the header will be available in
522  * #m_constructedPacketHeader.
523  * #m_constructedPacket will also be updated.
524  */
525  Receive(packet);
527 
529  {
530  /*
531  * There are more packets of this main object, so just stay still
532  * and wait until they arrive.
533  */
534  NS_LOG_INFO(this << " " << m_objectBytesToBeReceived << " byte(s)"
535  << " remains from this chunk of main object.");
536  }
537  else
538  {
539  /*
540  * This is the last packet of this main object. Acknowledge the
541  * reception of a whole main object
542  */
543  NS_LOG_INFO(this << " Finished receiving a main object.");
545 
546  if (!m_objectServerTs.IsZero())
547  {
549  m_objectServerTs = MilliSeconds(0); // Reset back to zero.
550  }
551 
552  if (!m_objectClientTs.IsZero())
553  {
555  m_objectClientTs = MilliSeconds(0); // Reset back to zero.
556  }
557 
559 
560  } // end of else of `if (m_objectBytesToBeReceived > 0)`
561 
562  } // end of `if (m_state == EXPECTING_MAIN_OBJECT)`
563  else
564  {
565  NS_FATAL_ERROR("Invalid state " << GetStateString() << " for ReceiveMainObject().");
566  }
567 
568 } // end of `void ReceiveMainObject (Ptr<Packet> packet)`
569 
570 void
572 {
573  NS_LOG_FUNCTION(this << packet << from);
574 
576  {
577  /*
578  * In the following call to Receive(), #m_objectBytesToBeReceived *will*
579  * be updated. #m_objectClientTs and #m_objectServerTs *may* be updated.
580  * ThreeGppHttpHeader will be removed from the packet, if it is the first
581  * packet of the object to be received; the header will be available in
582  * #m_constructedPacket, which will also be updated.
583  */
584  Receive(packet);
586 
588  {
589  /*
590  * There are more packets of this embedded object, so just stay
591  * still and wait until they arrive.
592  */
593  NS_LOG_INFO(this << " " << m_objectBytesToBeReceived << " byte(s)"
594  << " remains from this chunk of embedded object");
595  }
596  else
597  {
598  /*
599  * This is the last packet of this embedded object. Acknowledge
600  * the reception of a whole embedded object
601  */
602  NS_LOG_INFO(this << " Finished receiving an embedded object.");
604 
605  if (!m_objectServerTs.IsZero())
606  {
608  m_objectServerTs = MilliSeconds(0); // Reset back to zero.
609  }
610 
611  if (!m_objectClientTs.IsZero())
612  {
614  m_objectClientTs = MilliSeconds(0); // Reset back to zero.
615  }
616 
618  {
620  << " more embedded object(s) to be requested.");
621  // Immediately request another using the existing connection.
624  }
625  else
626  {
627  /*
628  * There is no more embedded object, the web page has been
629  * downloaded completely. Now is the time to read it.
630  */
631  NS_LOG_INFO(this << " Finished receiving a web page.");
632  FinishReceivingPage(); // trigger callback for page loading time
634  }
635 
636  } // end of else of `if (m_objectBytesToBeReceived > 0)`
637 
638  } // end of `if (m_state == EXPECTING_EMBEDDED_OBJECT)`
639  else
640  {
641  NS_FATAL_ERROR("Invalid state " << GetStateString() << " for ReceiveEmbeddedObject().");
642  }
643 
644 } // end of `void ReceiveEmbeddedObject (Ptr<Packet> packet)`
645 
646 void
648 {
649  NS_LOG_FUNCTION(this << packet);
650 
651  /* In a "real" HTTP message the message size is coded differently. The use of a header
652  * is to avoid the burden of doing a real message parser.
653  */
654  bool firstPacket = false;
655 
656  if (m_objectBytesToBeReceived == 0)
657  {
658  // This is the first packet of the object.
659  firstPacket = true;
660 
661  // Remove the header in order to calculate remaining data to be received.
662  ThreeGppHttpHeader httpHeader;
663  packet->RemoveHeader(httpHeader);
664 
666  m_objectClientTs = httpHeader.GetClientTs();
667  m_objectServerTs = httpHeader.GetServerTs();
668 
669  // Take a copy for constructed packet trace. Note that header is included.
670  m_constructedPacket = packet->Copy();
671  m_constructedPacket->AddHeader(httpHeader);
672  }
673  uint32_t contentSize = packet->GetSize();
674  m_numberBytesPage += contentSize; // increment counter of page size
675 
676  /* Note that the packet does not contain header at this point.
677  * The content is purely raw data, which was the only intended data to be received.
678  */
679  if (m_objectBytesToBeReceived < contentSize)
680  {
681  NS_LOG_WARN(this << " The received packet"
682  << " (" << contentSize << " bytes of content)"
683  << " is larger than"
684  << " the content that we expected to receive"
685  << " (" << m_objectBytesToBeReceived << " bytes).");
686  // Stop expecting any more packet of this object.
688  m_constructedPacket = nullptr;
689  }
690  else
691  {
692  m_objectBytesToBeReceived -= contentSize;
693  if (!firstPacket)
694  {
695  Ptr<Packet> packetCopy = packet->Copy();
696  m_constructedPacket->AddAtEnd(packetCopy);
697  }
698  }
699 
700 } // end of `void Receive (packet)`
701 
702 void
704 {
705  NS_LOG_FUNCTION(this);
706 
708  {
709  const Time parsingTime = m_httpVariables->GetParsingTime();
710  NS_LOG_INFO(this << " The parsing of this main object"
711  << " will complete in " << parsingTime.As(Time::S) << ".");
715  }
716  else
717  {
718  NS_FATAL_ERROR("Invalid state " << GetStateString() << " for EnterParsingTime().");
719  }
720 }
721 
722 void
724 {
725  NS_LOG_FUNCTION(this);
726 
728  {
729  m_embeddedObjectsToBeRequested = m_httpVariables->GetNumOfEmbeddedObjects();
730  // saving total number of embedded objects
732  NS_LOG_INFO(this << " Parsing has determined " << m_embeddedObjectsToBeRequested
733  << " embedded object(s) in the main object.");
734 
736  {
737  /*
738  * Immediately request the first embedded object using the
739  * existing connection.
740  */
743  }
744  else
745  {
746  /*
747  * There is no embedded object in the main object. So sit back and
748  * enjoy the plain web page.
749  */
750  NS_LOG_INFO(this << " Finished receiving a web page.");
751  FinishReceivingPage(); // trigger callback for page loading time
753  }
754  }
755  else
756  {
757  NS_FATAL_ERROR("Invalid state " << GetStateString() << " for ParseMainObject().");
758  }
759 
760 } // end of `void ParseMainObject ()`
761 
762 void
764 {
765  NS_LOG_FUNCTION(this);
766 
768  {
769  const Time readingTime = m_httpVariables->GetReadingTime();
770  NS_LOG_INFO(this << " Client will finish reading this web page in "
771  << readingTime.As(Time::S) << ".");
772 
773  // Schedule a request of another main object once the reading time expires.
777  }
778  else
779  {
780  NS_FATAL_ERROR("Invalid state " << GetStateString() << " for EnterReadingTime().");
781  }
782 }
783 
784 void
786 {
787  NS_LOG_FUNCTION(this);
788 
790  {
791  NS_LOG_INFO(this << " Canceling RequestMainObject() which is due in "
794  }
795 
797  {
798  NS_LOG_INFO(this << " Canceling RequestEmbeddedObject() which is due in "
800  << ".");
802  }
803 
805  {
806  NS_LOG_INFO(this << " Canceling ParseMainObject() which is due in "
809  }
810 }
811 
812 void
814 {
815  const std::string oldState = GetStateString();
816  const std::string newState = GetStateString(state);
817  NS_LOG_FUNCTION(this << oldState << newState);
818 
819  if ((state == EXPECTING_MAIN_OBJECT) || (state == EXPECTING_EMBEDDED_OBJECT))
820  {
822  {
823  NS_FATAL_ERROR("Cannot start a new receiving session"
824  << " if the previous object"
825  << " (" << m_objectBytesToBeReceived << " bytes)"
826  << " is not completely received yet.");
827  }
828  }
829 
830  m_state = state;
831  NS_LOG_INFO(this << " HttpClient " << oldState << " --> " << newState << ".");
832  m_stateTransitionTrace(oldState, newState);
833 }
834 
835 void
837 {
838  m_rxPageTrace(this,
842  // Reset counter variables.
844  m_numberBytesPage = 0;
845 }
846 
847 } // namespace ns3
a polymophic address class
Definition: address.h:101
The base class for all ns3 applications.
Definition: application.h:62
void DoDispose() override
Destructor implementation.
Definition: application.cc:86
Ptr< Node > GetNode() const
Definition: application.cc:108
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
An Inet6 address class.
static Inet6SocketAddress ConvertFrom(const Address &addr)
Convert the address to a InetSocketAddress.
uint16_t GetPort() const
Get the port.
static bool IsMatchingType(const Address &addr)
If the address match.
Ipv6Address GetIpv6() const
Get the IPv6 address.
an Inet address class
static bool IsMatchingType(const Address &address)
Ipv4Address GetIpv4() const
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:42
static Ipv4Address ConvertFrom(const Address &address)
static bool IsMatchingType(const Address &address)
Describes an IPv6 address.
Definition: ipv6-address.h:49
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:204
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:294
void AddAtEnd(Ptr< const Packet > packet)
Concatenate the input packet at the end of the current packet.
Definition: packet.cc:354
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:268
uint32_t GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:861
Ptr< Packet > Copy() const
performs a COW copy of the packet.
Definition: packet.cc:131
Hold objects of type Ptr<T>.
Definition: pointer.h:37
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:571
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:285
static bool IsFinished()
Check if the simulation should finish.
Definition: simulator.cc:171
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:208
static bool IsExpired(const EventId &id)
Check if an event has already run or been cancelled.
Definition: simulator.cc:295
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition: simulator.h:605
static Time GetDelayLeft(const EventId &id)
Get the remaining time until this event will execute.
Definition: simulator.cc:217
virtual int Send(Ptr< Packet > p, uint32_t flags)=0
Send data (or dummy data) to the remote host.
virtual Socket::SocketErrno GetErrno() const =0
Get last error number.
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:96
void SetRecvCallback(Callback< void, Ptr< Socket >> receivedData)
Notify application when new data is available to be read.
Definition: socket.cc:128
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.
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:72
virtual int Close()=0
Close a socket.
@ ERROR_NOTERROR
Definition: socket.h:85
virtual int Bind(const Address &address)=0
Allocate a local endpoint for this socket.
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:87
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()
Get the type ID.
ns3::TracedCallback< const Time &, const Address & > m_rxRttTrace
The RxRtt trace source.
Time m_pageLoadStartTs
The time stamp when the page started loading.
ns3::TracedCallback< Ptr< const ThreeGppHttpClient >, const Time &, uint32_t, uint32_t > m_rxPageTrace
The RxPage trace source.
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< const Time &, const Address & > m_rxDelayTrace
The RxDelay 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.
uint32_t m_numberEmbeddedObjectsRequested
Number of embedded objects to requested in the current page.
void ConnectionFailedCallback(Ptr< Socket > socket)
Invoked when m_socket cannot establish a connection with the web server.
ThreeGppHttpClient()
Creates a new instance of HTTP client application.
ns3::TracedCallback< Ptr< const Packet >, const Address & > m_rxTrace
The Rx trace source.
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.
void FinishReceivingPage()
Finish receiving a page.
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.
void EnterReadingTime()
Becomes idle for a randomly determined amount of time, and then triggers RequestMainObject().
void DoDispose() override
Destructor implementation.
void StartApplication() override
Application specific startup code.
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.
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.
uint32_t m_numberBytesPage
Number of bytes received for the current page.
Address m_remoteServerAddress
The RemoteServerAddress attribute. The address of the web server.
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.
void StopApplication() override
Application specific shutdown code.
ns3::TracedCallback< Ptr< const Packet > > m_rxMainObjectPacketTrace
The TxMainObjectPacket trace source.
ns3::TracedCallback< const std::string &, const std::string & > m_stateTransitionTrace
The StateTransition 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< 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:105
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:415
@ S
second
Definition: nstime.h:116
bool IsZero() const
Exactly equivalent to t == 0.
Definition: nstime.h:315
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:931
Hold an unsigned integer type.
Definition: uinteger.h:45
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#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:86
Callback< R, Args... > MakeNullCallback()
Definition: callback.h:747
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:254
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#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:261
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition: object.h:579
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1338
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, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:704
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Definition: pointer.h:227
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:46
static const uint32_t packetSize
Packet size generated at the AP.