--- a/examples/udp-echo.cc Mon Jun 22 18:29:43 2009 -0700
+++ b/examples/udp-echo.cc Tue Jun 23 19:44:57 2009 -0700
@@ -43,30 +43,10 @@
//
#if 0
LogComponentEnable ("UdpEchoExample", LOG_LEVEL_INFO);
-
- LogComponentEnable("Object", LOG_LEVEL_ALL);
- LogComponentEnable("Queue", LOG_LEVEL_ALL);
- LogComponentEnable("DropTailQueue", LOG_LEVEL_ALL);
- LogComponentEnable("Channel", LOG_LEVEL_ALL);
- LogComponentEnable("CsmaChannel", LOG_LEVEL_ALL);
- LogComponentEnable("NetDevice", LOG_LEVEL_ALL);
- LogComponentEnable("CsmaNetDevice", LOG_LEVEL_ALL);
- LogComponentEnable("Ipv4L3Protocol", LOG_LEVEL_ALL);
- LogComponentEnable("PacketSocket", LOG_LEVEL_ALL);
- LogComponentEnable("Socket", LOG_LEVEL_ALL);
- LogComponentEnable("UdpSocket", LOG_LEVEL_ALL);
- LogComponentEnable("UdpL4Protocol", LOG_LEVEL_ALL);
- LogComponentEnable("Ipv4L3Protocol", LOG_LEVEL_ALL);
- LogComponentEnable("Ipv4StaticRouting", LOG_LEVEL_ALL);
- LogComponentEnable("Ipv4Interface", LOG_LEVEL_ALL);
- LogComponentEnable("ArpIpv4Interface", LOG_LEVEL_ALL);
- LogComponentEnable("Ipv4LoopbackInterface", LOG_LEVEL_ALL);
- LogComponentEnable("OnOffApplication", LOG_LEVEL_ALL);
- LogComponentEnable("PacketSinkApplication", LOG_LEVEL_ALL);
LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_ALL);
LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_ALL);
#endif
-
+//
// Allow the user to override any of the defaults and the above Bind() at
// run-time, via command-line arguments
//
@@ -125,6 +105,19 @@
apps.Start (Seconds (2.0));
apps.Stop (Seconds (10.0));
+#if 0
+//
+// Users may find it convenient to initialize echo packets with actual data;
+// the below lines suggest how to do this
+//
+ client.SetFill(apps.Get (0), "Hello World");
+
+ client.SetFill(apps.Get (0), 0xa5, 1024);
+
+ uint8_t fill[] = {0, 1, 2, 3, 4, 5, 6};
+ client.SetFill(apps.Get (0), fill, sizeof(fill), 1024);
+#endif
+
std::ofstream ascii;
ascii.open ("udp-echo.tr");
CsmaHelper::EnablePcapAll ("udp-echo", false);
--- a/src/applications/udp-echo/udp-echo-client.cc Mon Jun 22 18:29:43 2009 -0700
+++ b/src/applications/udp-echo/udp-echo-client.cc Tue Jun 23 19:44:57 2009 -0700
@@ -57,9 +57,10 @@
UintegerValue (0),
MakeUintegerAccessor (&UdpEchoClient::m_peerPort),
MakeUintegerChecker<uint16_t> ())
- .AddAttribute ("PacketSize", "Size of packets generated",
+ .AddAttribute ("PacketSize", "Size of echo data in outbound packets",
UintegerValue (100),
- MakeUintegerAccessor (&UdpEchoClient::m_size),
+ MakeUintegerAccessor (&UdpEchoClient::SetDataSize,
+ &UdpEchoClient::GetDataSize),
MakeUintegerChecker<uint32_t> ())
;
return tid;
@@ -71,12 +72,18 @@
m_sent = 0;
m_socket = 0;
m_sendEvent = EventId ();
+ m_data = 0;
+ m_dataSize = 0;
}
UdpEchoClient::~UdpEchoClient()
{
NS_LOG_FUNCTION_NOARGS ();
m_socket = 0;
+
+ delete [] m_data;
+ m_data = 0;
+ m_dataSize = 0;
}
void
@@ -126,6 +133,106 @@
}
void
+UdpEchoClient::SetDataSize (uint32_t dataSize)
+{
+ NS_LOG_FUNCTION (dataSize);
+
+ //
+ // If the client is setting the echo packet data size this way, we infer
+ // that she doesn't care about the contents of the packet at all, so
+ // neither will we.
+ //
+ delete [] m_data;
+ m_data = 0;
+ m_dataSize = 0;
+ m_size = dataSize;
+}
+
+uint32_t
+UdpEchoClient::GetDataSize (void) const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return m_size;
+}
+
+void
+UdpEchoClient::SetFill (std::string fill)
+{
+ NS_LOG_FUNCTION (fill);
+
+ uint32_t dataSize = fill.size () + 1;
+
+ if (dataSize != m_dataSize)
+ {
+ delete [] m_data;
+ m_data = new uint8_t [dataSize];
+ m_dataSize = dataSize;
+ }
+
+ memcpy (m_data, fill.c_str (), dataSize);
+
+ //
+ // Overwrite packet size attribute.
+ //
+ m_size = dataSize;
+}
+
+void
+UdpEchoClient::SetFill (uint8_t fill, uint32_t dataSize)
+{
+ if (dataSize != m_dataSize)
+ {
+ delete [] m_data;
+ m_data = new uint8_t [dataSize];
+ m_dataSize = dataSize;
+ }
+
+ memset (m_data, fill, dataSize);
+
+ //
+ // Overwrite packet size attribute.
+ //
+ m_size = dataSize;
+}
+
+void
+UdpEchoClient::SetFill (uint8_t *fill, uint32_t fillSize, uint32_t dataSize)
+{
+ if (dataSize != m_dataSize)
+ {
+ delete [] m_data;
+ m_data = new uint8_t [dataSize];
+ m_dataSize = dataSize;
+ }
+
+ if (fillSize >= dataSize)
+ {
+ memcpy (m_data, fill, dataSize);
+ return;
+ }
+
+ //
+ // Do all but the final fill.
+ //
+ uint32_t filled = 0;
+ while (filled + fillSize < dataSize)
+ {
+ memcpy (&m_data[filled], fill, fillSize);
+ filled += fillSize;
+ }
+
+ //
+ // Last fill may be partial
+ //
+ memcpy(&m_data[filled], fill, dataSize - filled);
+
+ //
+ // Overwrite packet size attribute.
+ //
+ m_size = dataSize;
+}
+
+void
UdpEchoClient::ScheduleTransmit (Time dt)
{
NS_LOG_FUNCTION_NOARGS ();
@@ -139,8 +246,32 @@
NS_ASSERT (m_sendEvent.IsExpired ());
- Ptr<Packet> p = Create<Packet> (m_size);
- m_socket->Send (p);
+ if (m_dataSize)
+ {
+ //
+ // If m_dataSize is non-zero, we have a data buffer of the same size that we
+ // are expected to copy and send. This state of affairs is created if one of
+ // the Fill functions is called. In this case, m_size must have been set
+ // to agree with m_dataSize
+ //
+ NS_ASSERT_MSG (m_dataSize == m_size, "UdpEchoClient::Send(): m_size and m_dataSize inconsistent");
+ NS_ASSERT_MSG (m_data, "UdpEchoClient::Send(): m_dataSize but no m_data");
+ Ptr<Packet> p = Create<Packet> (m_data, m_dataSize);
+ m_socket->Send (p);
+ }
+ else
+ {
+ //
+ // If m_dataSize is zero, the client has indicated that she doesn't care
+ // about the data itself either by specifying the data size by setting
+ // the corresponding atribute or by not calling a SetFill function. In
+ // this case, we don't worry about it either. But we do allow m_size
+ // to have a value different from the (zero) m_dataSize.
+ //
+ Ptr<Packet> p = Create<Packet> (m_size);
+ m_socket->Send (p);
+ }
+
++m_sent;
NS_LOG_INFO ("Sent " << m_size << " bytes to " << m_peerAddress);
--- a/src/applications/udp-echo/udp-echo-client.h Mon Jun 22 18:29:43 2009 -0700
+++ b/src/applications/udp-echo/udp-echo-client.h Tue Jun 23 19:44:57 2009 -0700
@@ -46,6 +46,75 @@
void SetRemote (Ipv4Address ip, uint16_t port);
+ /**
+ * Set the data size of the packet (the number of bytes that are sent as data
+ * to the server). The contents of the data are set to unspecified (don't
+ * care) by this call.
+ *
+ * \warn If you have set the fill data for the echo client using one of the
+ * SetFill calls, this will undo those effects.
+ *
+ * \param dataSize The size of the echo data you want to sent.
+ */
+ void SetDataSize (uint32_t dataSize);
+
+ /**
+ * Get the number of data bytes that will be sent to the server.
+ *
+ * \warn The number of bytes may be modified by calling any one of the
+ * SetFill methods. If you have called SetFill, then the number of
+ * data bytes will correspond to the size of an initialized data buffer.
+ * If you have not called a SetFill method, the number of data bytes will
+ * correspond to the number of don't care bytes that will be sent.
+ *
+ * \returns The number of data bytes.
+ */
+ uint32_t GetDataSize (void) const;
+
+ /**
+ * Set the data fill of the packet (what is sent as data to the server) to
+ * the zero-terminated contents of the fill string string.
+ *
+ * \warn The size of resulting echo packets will be automatically adjusted
+ * to reflect the size of the fill string -- this means that the PacketSize
+ * attribute may be changed as a result of this call.
+ *
+ * \param fill The string to use as the actual echo data bytes.
+ */
+ void SetFill (std::string fill);
+
+ /**
+ * Set the data fill of the packet (what is sent as data to the server) to
+ * the repeated contents of the fill byte. i.e., the fill byte will be
+ * used to initialize the contents of the data packet.
+ *
+ * \warn The size of resulting echo packets will be automatically adjusted
+ * to reflect the dataSize parameter -- this means that the PacketSize
+ * attribute may be changed as a result of this call.
+ *
+ * \param fill The byte to be repeated in constructing the packet data..
+ * \param dataSize The desired size of the resulting echo packet data.
+ */
+ void SetFill (uint8_t fill, uint32_t dataSize);
+
+ /**
+ * Set the data fill of the packet (what is sent as data to the server) to
+ * the contents of the fill buffer, repeated as many times as is required.
+ *
+ * Initializing the packet to the contents of a provided single buffer is
+ * accomplished by setting the fillSize set to your desired dataSize
+ * (and providing an appropriate buffer).
+ *
+ * \warn The size of resulting echo packets will be automatically adjusted
+ * to reflect the dataSize parameter -- this means that the PacketSize
+ * attribute of the Application may be changed as a result of this call.
+ *
+ * \param fill The fill pattern to use when constructing packets.
+ * \param fillSize The number of bytes in the provided fill pattern.
+ * \param dataSize The desired size of the final echo data.
+ */
+ void SetFill (uint8_t *fill, uint32_t fillSize, uint32_t dataSize);
+
protected:
virtual void DoDispose (void);
@@ -63,6 +132,9 @@
Time m_interval;
uint32_t m_size;
+ uint32_t m_dataSize;
+ uint8_t *m_data;
+
uint32_t m_sent;
Ptr<Socket> m_socket;
Ipv4Address m_peerAddress;
--- a/src/helper/udp-echo-helper.cc Mon Jun 22 18:29:43 2009 -0700
+++ b/src/helper/udp-echo-helper.cc Tue Jun 23 19:44:57 2009 -0700
@@ -88,6 +88,24 @@
m_factory.Set (name, value);
}
+void
+UdpEchoClientHelper::SetFill (Ptr<Application> app, std::string fill)
+{
+ app->GetObject<UdpEchoClient>()->SetFill (fill);
+}
+
+void
+UdpEchoClientHelper::SetFill (Ptr<Application> app, uint8_t fill, uint32_t dataLength)
+{
+ app->GetObject<UdpEchoClient>()->SetFill (fill, dataLength);
+}
+
+void
+UdpEchoClientHelper::SetFill (Ptr<Application> app, uint8_t *fill, uint32_t fillLength, uint32_t dataLength)
+{
+ app->GetObject<UdpEchoClient>()->SetFill (fill, fillLength, dataLength);
+}
+
ApplicationContainer
UdpEchoClientHelper::Install (Ptr<Node> node) const
{
--- a/src/helper/udp-echo-helper.h Mon Jun 22 18:29:43 2009 -0700
+++ b/src/helper/udp-echo-helper.h Tue Jun 23 19:44:57 2009 -0700
@@ -52,6 +52,57 @@
void SetAttribute (std::string name, const AttributeValue &value);
+ /**
+ * Given a pointer to a UdpEchoClient application, set the data fill of the
+ * packet (what is sent as data to the server) to the contents of the fill
+ * string (including the trailing zero terminator).
+ *
+ * \warn The size of resulting echo packets will be automatically adjusted
+ * to reflect the size of the fill string -- this means that the PacketSize
+ * attribute may be changed as a result of this call.
+ *
+ * \param app Smart pointer to the application (real type must be UdpEchoClient).
+ * \param fill The string to use as the actual echo data bytes.
+ */
+ void SetFill (Ptr<Application> app, std::string fill);
+
+ /**
+ * Given a pointer to a UdpEchoClient application, set the data fill of the
+ * packet (what is sent as data to the server) to the contents of the fill
+ * byte.
+ *
+ * The fill byte will be used to initialize the contents of the data packet.
+ *
+ * \warn The size of resulting echo packets will be automatically adjusted
+ * to reflect the dataLength parameter -- this means that the PacketSize
+ * attribute may be changed as a result of this call.
+ *
+ * \param app Smart pointer to the application (real type must be UdpEchoClient).
+ * \param fill The byte to be repeated in constructing the packet data..
+ * \param dataLength The desired length of the resulting echo packet data.
+ */
+ void SetFill (Ptr<Application> app, uint8_t fill, uint32_t dataLength);
+
+ /**
+ * Given a pointer to a UdpEchoClient application, set the data fill of the
+ * packet (what is sent as data to the server) to the contents of the fill
+ * buffer, repeated as many times as is required.
+ *
+ * Initializing the fill to the contents of a single buffer is accomplished
+ * by providing a complete buffer with fillLength set to your desired
+ * dataLength
+ *
+ * \warn The size of resulting echo packets will be automatically adjusted
+ * to reflect the dataLength parameter -- this means that the PacketSize
+ * attribute of the Application may be changed as a result of this call.
+ *
+ * \param app Smart pointer to the application (real type must be UdpEchoClient).
+ * \param fill The fill pattern to use when constructing packets.
+ * \param fillLength The number of bytes in the provided fill pattern.
+ * \param dataLength The desired length of the final echo data.
+ */
+ void SetFill (Ptr<Application> app, uint8_t *fill, uint32_t fillLength, uint32_t dataLength);
+
ApplicationContainer Install (Ptr<Node> node) const;
ApplicationContainer Install (std::string nodeName) const;
ApplicationContainer Install (NodeContainer c) const;