[Ns-developers] Students, Sockets and Smart Pointers

craigdo@ee.washington.edu craigdo at ee.washington.edu
Thu Mar 27 15:36:41 PDT 2008


There's a discussion going on in the context of ns-3 bug 154 that I think
deserves a wider distribution.

Gustavo has reported a student who wrote some code to use sockets directly
which I reproduce at the end of the message. [If you happen to be the
student who wrote this code, I'm not pointing fingers at you.  I'm more
pointing fingers at the developers (me too) who led you down the path you
found yourself in.]

While there may be some issues with the semantics of socket lifetime
management that are being addressed in the bug tracker, IMO the important
issue uncovered here is much more fundamental.

First, let me make some rather blunt observations:

1) The code in question uses low-level ns-3 APIs;
2) The author does not understand the ns-3 object model and especially what
smart pointers do;
3) If you try and write low level code without understanding the object
model, you *will* fail (if not specifically on socket-related things, you'll
get bitten somewhere else).
4) There is deep confusion in this code about what is setup and what is
simulation;
5) If you try and write a simulation without understanding what is setup and
what is simulation, and how to kick start a simulation, you *will* fail.

To borrow a term from phase space, we seem to have set up an attractor that
led this student to a place where s/he was almost certain to fail in his
attempt to write something that should have been very, very simple.

Really, the student *should* have found his or her way into one of our
applications via one of our samples or examples and then modified one of
them slightly to do what he or she wanted.  That is what I would have hoped
would happen.

However, one of the things that "everybody knows" is that when you start
programming on an unfamiliar system, the thing to do is to look to use
sockets.  In ns-3, unfortunately, this usually reasonable approach leads you
immediately down into the heart of the system where probably *everything* is
unfamiliar and works in unexpected ways.  This is bad.  We have
unintentionally set this person up for failure by leading him or her into
the bowels of the system and saying, "here you go, have a nice day."

I think the solution to this particular problem is not to worry about what
part of the system holds on to references to sockets.  I think it is more
along the lines of making a simple socket helper-like thing that wraps up
all of the ns-3-specific stuff and makes doing something conceptually simple
actually simple in reality.  Over the past couple of weeks we seem to have
come to the conclusion that it is better to introduce folks slowly to our
beautiful, elegant but hard-to-grok low-level interfaces.  Our helpers are
all simple stack-based things.  This episode serves to reinforce the
correctness of that decision.

I think we need to have a simple simulation along the lines of one of the
canonical socket-based client-server apps that gives a starting place for
people like this student that doesn't involve having to delve so deeply into
the system; doesn't involve having to learn about the object model, etc.,
etc.  We need to be much clearer about what is simply setup, and what is
simulation and how we start things moving.  This is (to me) a surprisingly
subtle distinction for some folks.

I think an answer is to create and advertize an entry-level starting point
that probably doesn't involve anything deeper than a minimal subset of the
upcoming helper API and something that looks and feels as close to sockets
as is possible given our asynchronous environment.  This way, people who are
approaching ns-3 with the natural inclination to use sockets will be
"attracted" to the simple straightforward answer, not the "maze of twisty
little passages" that may be the result of finding oneself in the middle of
low-level ns-3 code.  They should find something that looks familiar when
they start.

If we have people that find themselves trying to program low-level ns-3
sockets without understanding what Ptr<Socket> means, or write a simulation
without understanding basics, it will certainly be a disaster.

I mean, in this case, the system behaved exactly how I would have expected
it to behave given what it was asked to do.

My $.02 anyway.

-- Craig

----------
class Test
{
public:

  void ReceivePacket (Ptr<Socket> socket, Ptr<Packet> packet, const Address
&from);
  bool run(void);
};

void Test::ReceivePacket (Ptr<Socket> socket, Ptr<Packet> packet, const
Address
&from)
{
  NS_LOG_INFO("receive packet");
  [...]
}

bool
Test::run(void)
{
[...] creates nodes [...]
    NS_LOG_INFO ("create socket  receive");
    Ptr<SocketFactory> socketFactory= rxNode->GetObject<Udp> ();
    Ptr<Socket> rxSocket= socketFactory->CreateSocket();
    rxSocket=->Bind (InetSocketAddress (Ipv4Address ("10.1.4.2"), 1234));
    rxSocket=->SetRecvCallback (MakeCallback (&Test::ReceivePacket, this));

    NS_LOG_INFO("send socket ");
    Ptr<SocketFactory> n0SocketFactory = n0->GetObject<Udp> ();
    Ptr<Socket> n0socket = n0SocketFactory->CreateSocket ();
    Ptr<Packet> packet=Create <Packet>();
    NS_LOG_INFO("....");
    n0socket->SendTo (InetSocketAddress (Ipv4Address("10.1.4.2"),
1234),packet); 

    return true;
}

int 
main (int argc, char *argv[])
{
  Test teste;
  teste.run();
[...]
  NS_LOG_INFO ("Run Simulation.");
  Simulator::StopAt (Seconds (3.0));
  Simulator::Run ();    
  Simulator::Destroy ();
  NS_LOG_INFO ("Done.");
}

----------




More information about the Ns-developers mailing list