added svn property keywords
[senf.git] / Example.dox
index f2d86f6..eb5a816 100644 (file)
 
     \dontinclude Sniffer.cc
 
-    The Sniffer application is a simple command line network sniffer
-    like \c tcpdump or \c tethereal. The application uses a packet
-    socket to read Ethernet packets from the \c eth0 interface and
-    dumps the parsed packets out to the standard output.
+    The Sniffer application is a simple command line network sniffer like \c tcpdump or \c
+    tethereal. The application uses a packet socket to read Ethernet packets from the \c eth0
+    interface and dumps the parsed packets out to the standard output.
 
-    We will be looking at \c Sniffer.cc in the \c Sniffer
-    directory. We start by including the necessary headers
+    To try out the example application, check out the library, go to the \c Sniffer
+    directory and execute
+
+    <pre>
+    # scons -u
+    # ./sniffer loop
+    < Hit Ctrl-C when you've seen enough >
+    # ./sniffer scheduler
+    < Hit Ctrl-C when you've seen enough >
+    </pre>
+
+    We will now look at the code which is found in \c Sniffer.cc in the \c Sniffer directory. The
+    code starts out by including the necessary headers
 
     \skip // Custom includes
-    \until Ethernet
+    \until membind
+
+    (The additional includes found in the source but not shown here are part of a short-time fix
+    which will be removed as soon as possible). The example application now contains a helper
+    routine to produce a packet hexdump. We will skip this routine here. The example includes two
+    implementations, one using blocking calls and a while loop, the other using the senf::Scheduler
+    for asynchronous event notification. They are implemented in \c loop_main() and \c
+    scheduler_main(). They will be documented below. For now, we skip these implementations and go
+    straight to the \c main() function
+
+    \skip int main(
+    \until return 1;
+    \until }
 
-    (The additional includes are part of a short-time fix which will
-    be removed as soon as possible). The example application now
-    contains a helper routine to produce a packet hexdump. We will
-    skip this routine here and go directly to the \c main function
-    
-    \skip main
+    This routine simply interprets the first command line argument and dispatches to the required
+    implementation.
+
+    Now lets go back and study each implementation in detail.
+
+    \dontinclude Sniffer.cc
+
+    \section example_loop A Blocking Implementation
+
+    This implementation is found in the \c loop_main function.
+
+    \skip loop_main
     \until try
 
-    We catch all exceptions in a \c try block. This is good for a
-    deliverable binary. When debugging the application, it might be
-    better to let the exception \c abort the execution so you can get
-    a backtrace of the exception origin in the debugger.
+    We catch all exceptions in a \c try block. This is good for a deliverable binary. When debugging
+    the application, it might be better to let the exception \c abort the execution so you can get a
+    backtrace of the exception origin in the debugger.
 
-    We now create a packet socket and bind it to the \c eth0
-    interface. By uncommenting the last line, you may switch the
-    interface into promiscuous mode.
+    We now create a packet socket and bind it to the \c eth0 interface. A packet socket is a linux
+    specific type of socket which returns ethernet packets directly from the network wire. By
+    uncommenting the last line, you may switch the interface into promiscuous mode.
 
     \until //
 
-    We will now read packets from the socket forever, that is until
-    the user hits Ctrl-C
+    We will now read packets from the socket forever, that is until the user hits Ctrl-C
 
     \skip while
     \until read
-    
-    The next step is, to parse the data read from the socket as an
-    Ethernet packet
+
+    The next step is, to parse the data read from the socket as an Ethernet packet
 
     \until ;
-    
-    Lets digest this line step by step: We declare a variable named \c
-    packet as a smart pointer to an \c EthernetPacket instance. \c ptr
-    is a typedef member of all Packet classes for the corresponding
-    smart pointer type. We then initialize this pointer with a call to
-    the static \c create member of the \c Packet class. This member
-    takes the type of Packet to parse as a template argument. We pass
-    \c EthernetPacket here. The function takes an iterator range as an
-    argument, and we pass it the complete packet just read by
-    giving the range \c begin() to \c end() of our just read \c data
-    string.
-
-    The next step is, to write out the packet to the standard output
+
+    Lets digest this line step by step: We declare a variable named \c packet as a smart pointer to
+    an \c EthernetPacket instance. \c ptr is a typedef member of all Packet classes for the
+    corresponding smart pointer type. We then initialize this pointer with a call to the static \c
+    create member of the \c Packet class. This member takes the type of Packet to parse as a
+    template argument. We pass \c EthernetPacket here. The function takes an iterator range as an
+    argument, and we pass it the complete packet just read by giving the range \c begin() to \c
+    end() of our just read \c data string.
+
+    The next step is to write out the packet to the standard output
 
     \until \n\n
 
-    The \c dump call will write out a complete representation of the
-    parsed packet data. The Packet library will \e not try to
-    interpret payload data as long as no exact indication of the
-    payload type is available (example: A UDP Payload is not parsed
-    further unless you explicitly tell the library, how to parse it).
-    Tools like \c tethereal guess the payload type by checking port
-    numbers and the payload data, however this is not advisable for a
-    general purpose packet library.
+    The \c dump call will write out a complete representation of the parsed packet data. The Packet
+    library will \e not try to interpret payload data as long as no exact indication of the payload
+    type is available (example: A UDP Payload is not parsed further unless you explicitly tell the
+    library, how to parse it).  Tools like \c tethereal guess the payload type by checking port
+    numbers and the payload data, however this is not advisable for a general purpose packet
+    library.
 
-    The next line, \c hexdump, will write out the \e last packet
-    component. Packets are managed as a chain of headers. The last
-    header is normally a \c DataPacket holding the payload data.
+    The next line, \c hexdump, will write out the \e last packet component. Packets are managed as a
+    chain of headers. The last header is normally a \c DataPacket holding the payload data.
 
-    That's it. We finish of by catching the exception and giving as
-    much detail as possible if an exception is caught
+    That's it. We finish of by catching the exception and giving as much detail as possible if an
+    exception is caught
 
     \until ;
     \until }
     \until }
 
-    The \c prettyName function from the \c Utils library is used, to
-    get a nice, printable representation of the \e dynamic type of the
-    exception instance. It is an interface to the g++ demangler. This
-    is necessary since the \c name member of the C++ \c type_info
-    instance is a mangled name in C++.
+    The \c prettyName function from the \c Utils library is used, to get a nice, printable
+    representation of the \e dynamic type of the exception instance. It is an interface to the g++
+    demangler. This is necessary since the \c name member of the C++ \c type_info instance is a
+    mangled name in \c g++.
+    
+    That's it for the simple blocking implementation. 
 
-    That's it. This is all, that's necessary to read and parse raw
-    network packets using the SENF library. To try out the example
-    application, check out the library, go to the \c Sniffer directory
-    and execute
+    \section example_scheduler Using the Scheduler
 
-    <pre>
-    # scons -u
-    # ./Sniffer
-    </pre>
+    However, we have another one which uses the Scheduler. We do this as it will be most of the
+    time: We define a class which manages reading the packets and dumping them out.
+
+    \until }
+
+    The class constructor binds the socket defined as a data member to the correct interface.
+
+    \until add
+
+    The public \c run() member is called to run the sniffer.  It first adds the socket to the
+    Scheduler. The \c add() call takes two Arguments, the socket to bind to (which can be a lot of
+    things and must not necessarily be a socket instance) and callback to call, whenever there is an
+    event on that socket. A third argument may be specified to restrict the events, on which the
+    function is called, here we have left out this argument which defaults to
+    senf::Scheduler::EV_ALL.
+
+    The callback is specified as a <a
+    href="http://www.boost.org/doc/html/function.html">Boost.Function</a> object. We use the \c
+    senf::membind helper from the Utils library to build such a function object. This helper takes
+    an arbitrary class member and binds it to a specific instance.
+
+    \until }
+
+    Calling the Schedulers \c process() method will start the event loop. This call does not return
+    (ok, it does return in special cases if \c senf::Scheduler::terminate() is called which does not
+    apply here).
+    
+    \until {
+
+    The \c dumpPacket() member is called by the scheduler whenever an event on the socket is
+    encountered. The scheduler always passes two arguments: The socket and an event id which
+    identifies the type of event which triggered the call.
+
+    \until };
+
+    The body is absolutely identical to the body of the \c while loop of the blocking
+    implementation. However, the scheduler guarantees, that a read on the socket will not block if
+    the socket is triggered to be readable (even if the socket is not set to non-blocking mode).
+
+    We now only need to provide the \c scheduler_main() function to run this code
+
+    \until 0;
+    \until }
+
+    This function is straight forward. The exception handling is the same as in \c loop_main(). The
+    code then just creates a \c Sniffer instance and calls it's \c run() member.
 
     \see \ref components \n
          \ref build \n
 \f
 // Local Variables:
 // mode: c++
+// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
 // mode: flyspell
 // mode: auto-fill
-// ispell-local-dictionary: "american"
 // End:
-